【问题标题】:stereo camera calibration error立体相机校准错误
【发布时间】:2018-10-12 17:07:11
【问题描述】:

我正在尝试对 2 个 USB 摄像头进行立体校准以执行深度图,但我遇到了这个错误,我不知道如何解决。 我将非常感谢谁能提供帮助。

 File "C:/Users/gaetano/stereoCalib.py", line 85, in <module>
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, 
gray.shape[::-1], None, None)

error: OpenCV(3.4.1) D:\Build\OpenCV\opencv- 
3.4.1\modules\calib3d\src\calibration.cpp:3384: error: (-215) nimages > 0 in 
function cv::calibrateCamera

(this error should have been solved using the following code) 



#before here i have collect picture from both the camera, than 
#grey conversion
i=0
while i < img_counter:
img = cv2.imread('colorRight_' + str(i) + '.jpg')
img2 = cv2.imread('colorLeft_' + str(i) + '.jpg')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

cv2.imwrite('greyRight_' + str(i) + '.jpg',gray)
cv2.imwrite('greyLeft_' + str(i) + '.jpg',gray2)
i += 1 



nx = 9
ny = 6
chess_imagesL = glob.glob('greyLeft_*.jpg')
chess_imagesR = glob.glob('greyRight_*.jpg')
for i in range(len(chess_imagesL)):
# Read in the image
chess_board_imageL = mpimg.imread(chess_imagesL[i])
chess_board_imageR = mpimg.imread(chess_imagesR[i])
# Convert to grayscale
# gray = cv2.cvtColor(chess_board_image, cv2.COLOR_RGB2GRAY)
# Find the chessboard corners
ret, cornersL = cv2.findChessboardCorners(chess_board_imageL, (nx, ny), 
None)
ret2, cornersR = cv2.findChessboardCorners(chess_board_imageR, (nx, ny), 
None)
# If found, draw corners
if ret == True:
    # Draw and display the corners
    cv2.drawChessboardCorners(chess_board_imageL, (nx, ny), cornersL, ret)
    cv2.drawChessboardCorners(chess_board_imageR, (nx, ny), cornersR, ret2)
    result_nameL = 'boardL'+str(i)+'.png'
    result_nameR = 'boardR'+str(i)+'.png'
    cv2.imwrite(result_nameL, chess_board_imageL)
    cv2.imwrite(result_nameR, chess_board_imageR)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

## prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*9,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)

objpointsL=[]
objpointsR=[]
imgpointsL=[]
imgpointsR=[]  


for i in range(len(chess_imagesL)):
# Read in the image
chess_board_imageL = mpimg.imread(chess_imagesL[i])
chess_board_imageR = mpimg.imread(chess_imagesR[i])

ret, cornersL = cv2.findChessboardCorners(chess_board_imageL, (nx, ny), 
None)
ret2, cornersR = cv2.findChessboardCorners(chess_board_imageR, (nx, ny), 
None)
# If found, draw corners
if ret == True:
    objpointsL.append(objp)
    objpointsR.append(objp)

    corners2L = cv2.cornerSubPix(gray,cornersL,(11,11),(-1,-1),criteria)
    corners2R = cv2.cornerSubPix(gray,cornersR,(11,11),(-1,-1),criteria)

    imgpointsL.append(corners2L)
    imgpointsR.append(corners2R)



    cv2.drawChessboardCorners(chess_board_imageL, (nx, ny), corners2L, ret)
    cv2.drawChessboardCorners(chess_board_imageR, (nx, ny), corners2R, ret2)
    result_nameL = 'boardL'+str(i)+'.png'
    result_nameR = 'boardR'+str(i)+'.png'
    cv2.imwrite(result_nameL, chess_board_imageL)
    cv2.imwrite(result_nameR, chess_board_imageR)

出现问题的部分

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpointsL, imgpointsL, 
gray.shape[::-1], None, None)
ret2, mtx2, dist2, rvecs2, tvecs2 = cv2.calibrateCamera(objpointsR, 
imgpointsR, gray2.shape[::-1], None, None)
R = []
T = []
E = []
F = []
flags = cv2.CALIB_FIX_INTRINSIC
ret, mtx, dist, mtx2, dist2, R, T, E, F = cv2.stereoCalibrate(objpointsL, 
imgpointsL ,imgpointsR, mtx, dist, mtx2, dist2, gray.shape[::-1], None, 
None, None, None,flags = flags,
criteria = (cv2.TERM_CRITERIA_EPS, 30, 1e-6))

更新 cv2.solvePnP 中的错误

使用您建议的代码,cameracalibration 似乎有效。但我在下一步有问题,立体相机校准

文件“C:/Users/gaetano/Desktop/sonido/CALIPROVA2.py”,第 157 行,在 ret, R, T = cv2.solvePnP(objpointsL,imgpointsL,mtx,dist,R,T,0,0)

TypeError: objectPoints 不是 numpy 数组,也不是标量

R = []
T = []
E = []
F = []
flags = cv2.CALIB_FIX_INTRINSIC

ret, mtx, dist, mtx2, dist2, R, T, E, F = cv2.stereoCalibrate(objpointsL, 
imgpointsL ,imgpointsR, mtxL, distL, mtxR, distR,
grayL.shape[::-1], None, None, None, None,
flags = flags,
criteria = (cv2.TERM_CRITERIA_EPS, 30, 1e-6))



ret, R, T = cv2.solvePnP(objpointsL,imgpointsL,mtx,dist,R,T,0,0)
print(R)
print(T)

调整大小

调整大小错误
SystemError: new style getargs format but argument is not a tuple

print(roi1)
print(roi2)
# crop the image
x, y, w, h = roi1
dst = dst[y:y + h, x:x + w]
#
dst2 = dst2[y:y + h, x:x + w]
dst = cv2.resize(dst, 0, dst, 2, 2, interpolation = cv2.INTER_LINEAR)

【问题讨论】:

  • 你有空的objpoints 在你附加一些东西的那一行被注释了
  • 感谢您的回答,但即使取消注释该行,错误仍然存​​在
  • 我认为 solvepnp 需要一组点,所以也许像 objpointsL[0] 和 imgpointsL[0] 这样的东西会起作用。

标签: opencv stereo-3d cv2 calibration


【解决方案1】:

所以错误说:

错误:OpenCV(3.4.1) D:\Build\OpenCV\opencv-3.4.1\modules\calib3d\src\calibration.cpp:3384: 错误:(-215) nimages > 0 in function cv::calibrateCamera

这意味着您将空列表变量作为对象点或图像点传递。

在您的代码中:

objpoints=[]
imgpoints=[]

然后仅在该行中使用:

#objpoints.append(objp)

并在行中:

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

这意味着两者都是空的!然后在函数中使用的那两个列表中没有任何内容。在下一行:

ret2, mtx2, dist2, rvecs2, tvecs2 = cv2.calibrateCamera(objpoints, imgpoints2, gray2.shape[::-1], None, None)

这里你使用imgpoints2,它存在并且有点,但是它没有objpoints(因为它被注释掉了),你会得到一个类似的错误。

解决方案:

您必须下定决心要在这里实现什么。如果是 2 次校准,那么将帧作为输入并完成所有过程的函数可能会更好。这样您就可以确保变量命名正确。

如果某个函数对您不利,那么您始终可以对imgpoints2imgpoints 执行相同的操作,并且可以使用该变量。此外,请确保取消注释 objpoints.append(objp) 以使该功能再次运行。

为了完整起见,这就是我对功能的意思:

def getObjPoints():
  objp = np.zeros((6*7,3), np.float32)
  objp[:,:2]=np.mgrid[0:7,0:6].T.reshape(-1,2)
  return objp

def calibrateCamWithFrame( frame ):
  objpoints=[getObjPoints]
  imgpoints=[]
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  ret, corners = cv2.findChessboardCorners(gray,(7,6),None)
  # if no corners where found return None
  if !ret:
    return None
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
  corners = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
  imgpoints.append(corners)
  frameWithCorners=cv2.drawChessboardCorners(frame,(7,6), corners, ret)
  cv2.imshow('img',frameWithCorners)
  cv2.waitKey(500)
  return cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

然后你会从外面打电话:

ret, mtx, dist, rvecs, tvecs = calibrateCamWithFrame(frame)
ret2, mtx2, dist2, rvecs2, tvecs2 = calibrateCamWithFrame(frame2)

更新

由于您想要校准 2 个摄像头,并对代码进行了适当的更改以识别它,因此解决方案是在主循环中读取图像、查找角点并附加数据。比如:

nx = 9
ny = 6
imgpointsL = []
imgpointsR = []
objpointsL = []
objpointsR = []
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)

for i in range(img_counter):
  grayR = cv2.imread('colorRight_' + str(i) + '.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE )
  grayL = cv2.imread('colorLeft_' + str(i) + '.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE )

  retR, cornersR = cv2.findChessboardCorners(grayR, (nx, ny), None)
  if retR:
     cornersR = cv2.cornerSubPix(gray, cornersR, (11,11), (-1,-1), criteria)
     imgpointsR.append(cornersR)
     objpointsR.append(objp)

  retL, cornersL = cv2.findChessboardCorners(grayL, (nx, ny), None)

  if retL:
     cornersL = cv2.cornerSubPix(gray, cornersL, (11,11), (-1,-1), criteria)
     imgpointsL.append(cornersR)
     objpointsL.append(objp)

现在您可以校准每个摄像头,注意我为每个摄像头使用 imgpoints 和 objpoints...这样您就可以确保尺寸匹配,因为不一定一个摄像头中的所有图像都能正确找到角点。

然后你可以校准,确保你有图像:

  if len(imgpointsL) >0:
    retL, mtxL, distL, rvecsL, tvecsL = cv2.calibrateCamera(objpointsL, imgpointsL,grayL.shape[::-1], None, None)

  if len(imgpointsL) >0:
    retR, mtxR, distR, rvecsR, tvecsR = cv2.calibrateCamera(objpointsR, imgpointsR,grayR.shape[::-1], None, None)

【讨论】:

  • 感谢您提供的帮助。就一个问题。如果我不使用该功能,我必须将imgpoint获取放在一个循环中?
  • @gaetanoma 我不确定你的目标到底是什么......但我想你想在一次校准计算中使用所有图像(这是典型情况),对吧?我放这个函数是因为你做了 2 次相同的代码......但通常你应该在循环中找到角点,如果找到将点附加到 imgpoint 并且 objpoints 添加另一个 objp(所以它们的大小匹配)我可以更新如果这就是你的目标,那么答案......
  • 是的。我从 2 个相机拍照,然后保存图片,转换为灰色并绘制棋盘。我的意图是首先对两个相机进行校准,而不是进行立体校准。我已经更改了我的代码,所以你可以在第一篇文章中看到我做了什么
  • 好的,感谢您的帮助,我想找到一个解决方案,将所有内容都放在循环中。但现在我有另一个问题,因为 cv2.calibrateCamera 工作,但我有一个错误 R = [] T = [] E = [] F = [] flags = cv2.CALIB_FIX_INTRINSIC ret, R, T = cv2.solvePnP(objpointsL ,imgpointsL,mtx,dist,R,T,0,0) 它说 objpoints 不是 numpy 数组,也不是标量
  • @gaetanoma 我更新了我的答案:) 看看
猜你喜欢
  • 2018-12-15
  • 2020-10-16
  • 2023-03-23
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多