这是我在stackoverflow上的第一篇文章。如果我的英语和编程知识有所影响,请原谅。
好的,我正在尝试在Windows 8.1操作系统中使用OpenCV 2.4.9进行相机标定(Ubuntu操作系统无法解决问题)。
问题:我正在使用下面的代码对相机进行标定,但似乎如果我的样本图像(带有棋盘格图案)数量超过2个,则newcameramtx、roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))的ROI结果为[0,0,0,0]。样本数与该结果有何关系?(在更改此代码之前,先前的最大样本数为12)。
说到最大样本数,我的意思是从我的相机获取的带有棋盘格图案的图像,如果数量超过最大数量,那么ROI将不能给出良好的结果。
角点检测非常好。您可以在这里找到我的示例图像。
# -*- coding: utf-8 -*-
"""
Created on Fri May 16 15:23:00 2014
@author: kakarot
"""
import numpy as np
import cv2
#import os
#import time
from matplotlib import pyplot as plt
LeftorRight = 'L'
numer = 12
chx = 6
chy = 9
chd = 25
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, numer, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((chy*chx,3), np.float32)
objp[:,:2] = np.mgrid[0:chy,0:chx].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space, (x25mm)
imgpoints = [] # 2d points in image plane.
enum = 1
while(enum<=numer):
img=cv2.imread('1280x720p/BestAsPerMatlab/calib_'+str(LeftorRight)+str(enum)+'.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (chy,chx),None)
#cv2.imshow('Calibration',img)
# If found, add object points, image points (after refining them)
if ret == True and enum <= numer:
objpoints.append(objp*chd)
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (chy,chx),corners,ret)
cv2.imshow('Calibration',img)
cv2.imwrite('1280x720p/Chessboard/calibrated_L{0}.jpg'.format(enum),img)
print enum
#time.sleep(2)
if enum == numer:
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
img = cv2.imread('1280x720p/BestAsPerMatlab/calib_'+str(LeftorRight)+'7.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
h, w = img.shape[:2] #a (1 to see the whole picture)
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
if (np.size(roi) == 4 and np.mean(roi) != 0):
# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
dst = cv2.cvtColor(dst,cv2.COLOR_RGB2BGR)
plt.imshow(dst)
#cv2.imwrite('result.jpg',dst)
#np.savetxt('mtxL.txt',mtx)
#np.savetxt('distL.txt',dist)
else:
np.disp('Something Went Wrong')
enum += 1
'''
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
'''
cv2.destroyAllWindows()
编辑: 我正在使用两个廉价的USB相机。我发现一个相机的样本集很好,而且我可以使用超过19个样本而没有问题。但是当使用另一个相机的校准样本时,最多只能使用2个样本图像。(如果我制作另一个样本集,数量将会有所变化)。总的来说,似乎存在某些与所产生校准矩阵相关的问题。但这是很奇怪的。
最后,我正在使用鱼眼相机,认为在每次拍摄的末端裁剪足够的像素就可以模拟普通相机......也许这就是导致我麻烦的原因!