opencv立体标定结果
opencv stereo calibration result
好像我有两个网络摄像头,标记为cam1
,cam2
。我想校准它们以获得它们之间的转换。
我用cv::stereoCalibrate()
校准了。
我得到cam1
到cam2
的转换后,标记为R
,T
。我想检查校准结果的准确性。
所以我用cam1
和cam2
拍了一张棋盘,标记为pic1
,pic2
。我得到了cam1
' cv::solvePnP()
.s 外部参数。我在 pic1
.
中通过 cv::projectPoints()
绘制了 cam1
的世界坐标系
那么,我认为cam2
的旋转矩阵=cam1
的旋转矩阵*R
。而cam2
的平移矩阵=cam1
的平移矩阵+T
.
我通过上面计算了cam2
的外参数thought.And也通过cv::projectPoints()
在pic2
中绘制了cam2
的世界坐标系.
但是pic2
的原点位置不对
这是我使用的部分代码。
void check_res(const vector<string> &imgs_nm,const Mat &R,const Mat &T,const Mat &cam_c,const Mat &cam_h,const Mat &dist_c,const Mat &dist_h)
{
int imgs_cnt=imgs_nm.size()/2;
vector<Point3f> obj_pts;
for(int i=0;i<boardDimensions.height;i++)
for(int j=0;j<boardDimensions.width;j++)
obj_pts.push_back(Point3f(i*CHESS_LEN,j*CHESS_LEN,0.f));
for(int i=0;i<imgs_cnt;i++)
{
vector<Point2f> c_cners,h_cners;
Mat imgc_gray,imgh_gray;
Mat imgc=imread(imgs_nm[i*2],1);
Mat imgc_rz=imgc.clone();
bool c_found,h_found;
c_found=HasChessBoard(imgc_rz,imgc_gray,c_cners);
if(c_found)
cv::cornerSubPix(imgc_gray, c_cners, cv::Size(11, 11), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
Mat imgh=imread(imgs_nm[i*2+1],1);
h_found=HasChessBoard(imgh,imgh_gray,h_cners);
if(h_found)
cv::cornerSubPix(imgh_gray, h_cners, cv::Size(11, 11), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
Mat rvec_c,rvec_h,tvec_c,tvec_h;
cv::solvePnP(obj_pts,c_cners,cam_c,dist_c,rvec_c,tvec_c);
cv::solvePnP(obj_pts,h_cners,cam_h,dist_h,rvec_h,tvec_h);
Mat rrvec_c,rrvec_h;
cv::Rodrigues(rvec_c,rrvec_c);
cv::Rodrigues(rvec_h,rrvec_h);
Mat r1=rrvec_c*R;
Mat t1=tvec_c+T;
Mat img1=imgh.clone();
draw_chess(imgh,rrvec_h,tvec_h,cam_h,dist_h);
imshow("pic1",imgh);
draw_chess(img1,r1,t1,cam_h,dist_h);
imshow("pic2",img1);
char resc=waitKey(0);
if(resc=='q')
exit(1);
}
}
下面是我使用opencv
.
中的样本测试的结果
我不认为这是校准精度低,因为我使用opencv
的样本和cv::stereoCalibrate()
return rms小于1像素。
如有任何建议,我们将不胜感激。
谢谢!
公式为:
- 相机 1 的姿势(在齐次矩阵中):
- 从相机 1 到相机 2 的均匀变换:
- 相机 2 的姿势:
为了检查立体校准的准确性,我会考虑一种不同的方法:
- 使用函数
stereoRectify
获取相机的整流变换。使用从 stereoCalibrate
. 获得的平移和旋转矩阵
- 对每个摄像头执行一次
initUndistortRectifyMap
。使用
- 使用您获得的结果
remap
来自两个相机的图像。
如果校准顺利,输出的图像应该经过校正且没有失真。
好像我有两个网络摄像头,标记为cam1
,cam2
。我想校准它们以获得它们之间的转换。
我用cv::stereoCalibrate()
校准了。
我得到cam1
到cam2
的转换后,标记为R
,T
。我想检查校准结果的准确性。
所以我用cam1
和cam2
拍了一张棋盘,标记为pic1
,pic2
。我得到了cam1
' cv::solvePnP()
.s 外部参数。我在 pic1
.
cv::projectPoints()
绘制了 cam1
的世界坐标系
那么,我认为cam2
的旋转矩阵=cam1
的旋转矩阵*R
。而cam2
的平移矩阵=cam1
的平移矩阵+T
.
我通过上面计算了cam2
的外参数thought.And也通过cv::projectPoints()
在pic2
中绘制了cam2
的世界坐标系.
但是pic2
的原点位置不对
这是我使用的部分代码。
void check_res(const vector<string> &imgs_nm,const Mat &R,const Mat &T,const Mat &cam_c,const Mat &cam_h,const Mat &dist_c,const Mat &dist_h)
{
int imgs_cnt=imgs_nm.size()/2;
vector<Point3f> obj_pts;
for(int i=0;i<boardDimensions.height;i++)
for(int j=0;j<boardDimensions.width;j++)
obj_pts.push_back(Point3f(i*CHESS_LEN,j*CHESS_LEN,0.f));
for(int i=0;i<imgs_cnt;i++)
{
vector<Point2f> c_cners,h_cners;
Mat imgc_gray,imgh_gray;
Mat imgc=imread(imgs_nm[i*2],1);
Mat imgc_rz=imgc.clone();
bool c_found,h_found;
c_found=HasChessBoard(imgc_rz,imgc_gray,c_cners);
if(c_found)
cv::cornerSubPix(imgc_gray, c_cners, cv::Size(11, 11), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
Mat imgh=imread(imgs_nm[i*2+1],1);
h_found=HasChessBoard(imgh,imgh_gray,h_cners);
if(h_found)
cv::cornerSubPix(imgh_gray, h_cners, cv::Size(11, 11), cv::Size(-1, -1),cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
Mat rvec_c,rvec_h,tvec_c,tvec_h;
cv::solvePnP(obj_pts,c_cners,cam_c,dist_c,rvec_c,tvec_c);
cv::solvePnP(obj_pts,h_cners,cam_h,dist_h,rvec_h,tvec_h);
Mat rrvec_c,rrvec_h;
cv::Rodrigues(rvec_c,rrvec_c);
cv::Rodrigues(rvec_h,rrvec_h);
Mat r1=rrvec_c*R;
Mat t1=tvec_c+T;
Mat img1=imgh.clone();
draw_chess(imgh,rrvec_h,tvec_h,cam_h,dist_h);
imshow("pic1",imgh);
draw_chess(img1,r1,t1,cam_h,dist_h);
imshow("pic2",img1);
char resc=waitKey(0);
if(resc=='q')
exit(1);
}
}
下面是我使用opencv
.
我不认为这是校准精度低,因为我使用opencv
的样本和cv::stereoCalibrate()
return rms小于1像素。
如有任何建议,我们将不胜感激。 谢谢!
公式为:
- 相机 1 的姿势(在齐次矩阵中):
- 从相机 1 到相机 2 的均匀变换:
- 相机 2 的姿势:
为了检查立体校准的准确性,我会考虑一种不同的方法:
- 使用函数
stereoRectify
获取相机的整流变换。使用从stereoCalibrate
. 获得的平移和旋转矩阵
- 对每个摄像头执行一次
initUndistortRectifyMap
。使用 - 使用您获得的结果
remap
来自两个相机的图像。
如果校准顺利,输出的图像应该经过校正且没有失真。