因为前一阵子忙于自己的毕设,所以就没有及时更新日志,今天正好没其他事儿,所以,我就把图像拼接程序写上来了。。。欢迎大家的阅读以及批评和指正。 下面的程序是基于opencv2.3.1+vs2010的搭建的环境下编程的。。。 首先对两个usb通用摄像头进行了标定。然后进行图像拼接,最后进行测距。 这不是最终版,因为最终版是我的论文内容。 所以,要过一阵子才能写上来,因为现在写上来我的论文可能被互联网的查重率坑爹的。。。 呵呵,请大家见谅。。。不过,很多重点代码都是完好无损的。。。。 #include <math.h> #include <ctime> #include <cv.h> #include <highgui.h> #include <features2d/features2d.hpp> #include <cvaux.h> #include <string> #include <iostream> #include <fstream> using namespace std; using namespace cv; void main() { ofstream fout("Result.txt"); float f_left[2],f_right[2]; IplImage * show; //RePlay图像指针 cvNamedWindow("RePlay",1); int number_image_copy=7; //复制图像帧数 CvSize board_size=cvSize(9,6); //标定板角点数 CvSize2D32f square_size=cvSize2D32f(10,10); //假设我的每个标定方格长宽都是1.82厘米 float square_length=square_size.width; //方格长度 float square_height=square_size.height; //方格高度 int board_width=board_size.width; //每行角点数 int board_height=board_size.height; //每列角点数 int total_per_image=board_width*board_height; //每张图片角点总数 int count; //存储每帧图像中实际识别的角点数 int found; //识别标定板角点的标志位 int step; //存储步长,step=successes*total_per_image; int successes=0; //存储成功找到标定板上所有角点的图像帧数 int a=1; //临时变量,表示在操作第a帧图像 const int NImages = 7;//图片总数 CvMat *rotation_vectors; CvMat *translation_vectors; CvPoint2D32f * image_points_buf = new CvPoint2D32f[total_per_image]; //存储角点图像坐标的数组 CvMat * image_points=cvCreateMat(NImages*total_per_image,2,CV_32FC1);//存储角点的图像坐标的矩阵 CvMat * object_points=cvCreateMat(NImages*total_per_image,3,CV_32FC1);//存储角点的三维坐标的矩阵 CvMat * point_counts=cvCreateMat(NImages,1,CV_32SC1);//存储每帧图像的识别的角点数 CvMat * intrinsic_matrix=cvCreateMat(3,3,CV_32FC1);//内参数矩阵 CvMat * distortion_coeffs=cvCreateMat(5,1,CV_32FC1);//畸变系数 rotation_vectors = cvCreateMat(NImages,3,CV_32FC1);//旋转矩阵 translation_vectors = cvCreateMat(NImages,3,CV_32FC1);//平移矩阵 ifstream fin("calibdata1.txt"); /* 定标所用图像文件的路径 */ while(a<=number_image_copy) { //sprintf_s (filename,"%d.jpg",a); string filename; getline(fin,filename); show=cvLoadImage(filename.c_str(),1); //寻找棋盘图的内角点位置 found=cvFindChessboardCorners(show,board_size,image_points_buf,&count, CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS); if (found==0) { //如果没找到标定板角点时 cout<<"第"<<a<<"帧图片无法找到棋盘格所有角点!\n\n"; fout<<"第"<<a<<"帧图片无法找到棋盘格所有角点!\n\n"; cvNamedWindow("RePlay",1); cvShowImage("RePlay",show); cvWaitKey(2000); } else { //找到标定板角点时 cout<<"第"<<a<<"帧图像成功获得"<<count<<"个角点...\n"; fout<<"第"<<a<<"帧图像成功获得"<<count<<"个角点...\n"; cvNamedWindow("RePlay",1); IplImage * gray_image= cvCreateImage(cvGetSize(show),8,1); cvCvtColor(show,gray_image,CV_BGR2GRAY); cout<<"获取源图像灰度图过程完成...\n"; fout<<"获取源图像灰度图过程完成...\n"; cvFindCornerSubPix(gray_image,image_points_buf,count,cvSize(11,11),cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1)); cout<<"灰度图亚像素化过程完成...\n"; fout<<"灰度图亚像素化过程完成...\n"; cvDrawChessboardCorners(show,board_size,image_points_buf,count,found); cout<<"在源图像上绘制角点过程完成...\n\n"; fout<<"在源图像上绘制角点过程完成...\n\n"; cvShowImage("RePlay",show); cvWaitKey(500); } if(total_per_image==count) { step=successes*total_per_image; //计算存储相应坐标数据的步长 for(int i=step,j=0;j<total_per_image;++i,++j) { CV_MAT_ELEM(*image_points, float,i,0)=image_points_buf[j].x; CV_MAT_ELEM(*image_points, float,i,1)=image_points_buf[j].y; CV_MAT_ELEM(*object_points,float,i,0)=(float)((j/board_width)*square_length); CV_MAT_ELEM(*object_points,float,i,1)=(float)((j%board_width)*square_height); CV_MAT_ELEM(*object_points,float,i,2)=0.0f; } CV_MAT_ELEM(*point_counts,int,successes,0)=total_per_image; successes++; } cout<<"hahahahh======"<<a<<endl; fout<<"hahahahh======"<<a<<endl; a++; } cvReleaseImage(&show); cvDestroyWindow("RePlay"); cout<<"*********************************************\n"; fout<<"*********************************************\n"; cout<<NImages<<"帧图片中,标定成功的图片为"<<successes<<"帧...\n"; fout<<NImages<<"帧图片中,标定成功的图片为"<<successes<<"帧...\n"; cout<<NImages<<"帧图片中,标定失败的图片为"<<NImages-successes<<"帧...\n\n"; fout<<NImages<<"帧图片中,标定失败的图片为"<<NImages-successes<<"帧...\n\n"; cout<<"*********************************************\n\n"; fout<<"*********************************************\n\n"; cout<<"按任意键开始计算摄像机内参数...\n\n"; fout<<"按任意键开始计算摄像机内参数...\n\n"; /*CvCapture* capture1; capture1 = cvCreateCameraCapture(0);*/ IplImage * show_colie; show_colie = cvLoadImage("F:\\graduatelunwen\\opencvprojects\\june\\opecv_ransac_sift_cameraCalibration\\dinggao_wanchengban_sift_ransac\\left_43.jpg",1); CvMat * object_points2 = cvCreateMat(successes*total_per_image,3,CV_32FC1); CvMat * image_points2 = cvCreateMat(successes*total_per_image,2,CV_32FC1); CvMat * point_counts2 = cvCreateMat(successes,1,CV_32SC1); for(int i=0;i<successes*total_per_image;++i) { CV_MAT_ELEM(*image_points2, float,i,0)=CV_MAT_ELEM(*image_points, float,i,0); CV_MAT_ELEM(*image_points2, float,i,1)=CV_MAT_ELEM(*image_points, float,i,1); CV_MAT_ELEM(*object_points2,float,i,0)=CV_MAT_ELEM(*object_points,float,i,0); CV_MAT_ELEM(*object_points2,float,i,1)=CV_MAT_ELEM(*object_points,float,i,1); CV_MAT_ELEM(*object_points2,float,i,2)=CV_MAT_ELEM(*object_points,float,i,2); } for(int i=0;i<successes;++i) { CV_MAT_ELEM(*point_counts2,int,i,0) = CV_MAT_ELEM(*point_counts,int,i,0); } cvReleaseMat(&object_points); cvReleaseMat(&image_points); cvReleaseMat(&point_counts); CV_MAT_ELEM(*intrinsic_matrix,float,0,0)=1.0f; CV_MAT_ELEM(*intrinsic_matrix,float,1,1)=1.0f; cvCalibrateCamera2(object_points2,image_points2,point_counts2,cvGetSize(show_colie), intrinsic_matrix,distortion_coeffs,rotation_vectors,translation_vectors,0); cout<<"摄像机内参数矩阵为:\n"; fout<<"摄像机内参数矩阵为:\n"; cout<<CV_MAT_ELEM(*intrinsic_matrix,float,0,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,2) <<"\n\n"; cout<<CV_MAT_ELEM(*intrinsic_matrix,float,1,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,2) <<"\n\n"; cout<<CV_MAT_ELEM(*intrinsic_matrix,float,2,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,2) <<"\n\n"; fout<<CV_MAT_ELEM(*intrinsic_matrix,float,0,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,0,2) <<"\n\n"; fout<<CV_MAT_ELEM(*intrinsic_matrix,float,1,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,1,2) <<"\n\n"; fout<<CV_MAT_ELEM(*intrinsic_matrix,float,2,0)<<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,1) <<" "<<CV_MAT_ELEM(*intrinsic_matrix,float,2,2) <<"\n\n"; f_left[0]=CV_MAT_ELEM(*intrinsic_matrix,float,0,0); f_left[1]=CV_MAT_ELEM(*intrinsic_matrix,float,1,1); cout<<"畸变系数矩阵为:\n"; cout<<CV_MAT_ELEM(*distortion_coeffs,float,0,0)<<" "<<CV_MAT_ELEM(*distortion_coeffs,float,1,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,2,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,3,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,4,0) <<"\n\n"; fout<<"畸变系数矩阵为:\n"; fout<<CV_MAT_ELEM(*distortion_coeffs,float,0,0)<<" "<<CV_MAT_ELEM(*distortion_coeffs,float,1,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,2,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,3,0) <<" "<<CV_MAT_ELEM(*distortion_coeffs,float,4,0) <<"\n\n"; cvSave("Intrinsics.xml",intrinsic_matrix); cvSave("Distortion.xml",distortion_coeffs); cout<<"摄像机矩阵、畸变系数向量已经分别存储在名为Intrinsics.xml、Distortion.xml文档中\n\n"; fout<<"摄像机矩阵、畸变系数向量已经分别存储在名为Intrinsics.xml、Distortion.xml文档中\n\n"; for(int ii = 0; ii < NImages; ++ii) { float tranv[3] = {0.0}; float rotv[3] = {0.0}; for ( int i = 0; i < 3; i++) { tranv[i] = ((float*)(translation_vectors->data.ptr+ii*translation_vectors->step))[i]; rotv[i] = ((float*)(rotation_vectors->data.ptr+rotation_vectors->step))[i]; } cout << "第" << ii+1 << "幅图的外参数" << endl; fout << "第" << ii+1 << "幅图的外参数" << endl; printf("ROTATION VECTOR 旋转向量 : \n"); printf("[ %6.4f %6.4f %6.4f ] \n", rotv[0], rotv[1], rotv[2]); printf("TRANSLATION VECTOR 平移向量: \n"); printf("[ %6.4f %6.4f %6.4f ] \n", tranv[0], tranv[1], tranv[2]); printf("-----------------------------------------\n"); fout<<"ROTATION VECTOR 旋转向量 : \n"<<endl; fout<< rotv[0]<<" "<< rotv[1]<<" "<< rotv[2]<<endl; fout<<"TRANSLATION VECTOR 平移向量: \n"<<endl; fout<< tranv[0]<<" "<< tranv[1]<< " "<<tranv[2]<<endl; fout<<"-----------------------------------------\n"<<endl; } CvMat * intrinsic=(CvMat *)cvLoad("Intrinsics.xml"); CvMat * distortion=(CvMat *)cvLoad("Distortion.xml"); IplImage * mapx=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1); IplImage * mapy=cvCreateImage(cvGetSize(show_colie),IPL_DEPTH_32F,1); cvInitUndistortMap(intrinsic,distortion,mapx,mapy); cvNamedWindow("原始图像",1); cvNamedWindow("非畸变图像",1); // cout<<"按‘E’键退出显示...\n\n"; /*while(show_colie) {*/ IplImage * clone=cvCloneImage(show_colie); cvShowImage("原始图像",show_colie); cvRemap(clone,show_colie,mapx,mapy); cvReleaseImage(&clone); cvShowImage("非畸变图像",show_colie); cvWaitKey(500); /*if(cvWaitKey(10)=='e') { break; }*/ /*show_colie=cvQueryFrame(capture1); }*/ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////// ////////////////////////////////////////////// ////////// 右摄像机标定 ////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// IplImage * showR; //RePlay图像指针 cvNamedWindow("RePlayR",1); int number_image_copyR=7; //复制图像帧数 CvSize board_sizeR=cvSize(9,6); //标定板角点数 CvSize2D32f square_sizeR=cvSize2D32f(10,10); //假设我的每个标定方格长宽都是1.82厘米 float square_lengthR=square_sizeR.width; //方格长度 float square_heightR=square_sizeR.height; //方格高度 int board_widthR=board_sizeR.width; //每行角点数 int board_heightR=board_sizeR.height; //每列角点数 int total_per_imageR=board_widthR*board_heightR; //每张图片角点总数 int countR; //存储每帧图像中实际识别的角点数 int foundR; //识别标定板角点的标志位 int stepR; //存储步长,stepR=successesR*total_per_imageR; int successesR=0; //存储成功找到标定板上所有角点的图像帧数 int aR=1; //临时变量,表示在操作第a帧图像 const int NImagesR = 7;//图片总数 CvMat *rotation_vectorsR; CvMat *translation_vectorsR; CvPoint2D32f * image_pointsR_bufR = new CvPoint2D32f[total_per_imageR]; //存储角点图像坐标的数组 CvMat * image_pointsR=cvCreateMat(NImagesR*total_per_imageR,2,CV_32FC1);//存储角点的图像坐标的矩阵 CvMat * object_pointsR=cvCreateMat(NImagesR*total_per_imageR,3,CV_32FC1);//存储角点的三维坐标的矩阵 CvMat * point_countRsR=cvCreateMat(NImagesR,1,CV_32SC1);//存储每帧图像的识别的角点数 CvMat * intrinsicR_matrixR=cvCreateMat(3,3,CV_32FC1);//内参数矩阵 CvMat * distortionR_coeffsR=cvCreateMat(5,1,CV_32FC1);//畸变系数 rotation_vectorsR = cvCreateMat(NImagesR,3,CV_32FC1);//旋转矩阵 translation_vectorsR = cvCreateMat(NImagesR,3,CV_32FC1);//平移矩阵 ifstream finR("calibdata2.txt"); /* 定标所用图像文件的路径 */ while(aR<=number_image_copyR) { //sprintf_s (filename,"%d.jpg",a); string filenameR; getline(finR,filenameR); showR=cvLoadImage(filenameR.c_str(),1); //寻找棋盘图的内角点位置 foundR=cvFindChessboardCorners(showR,board_sizeR,image_pointsR_bufR,&countR, CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS); if (foundR==0) { //如果没找到标定板角点时 cout<<"第"<<aR<<"帧图片无法找到棋盘格所有角点!\n\n"; fout<<"第"<<aR<<"帧图片无法找到棋盘格所有角点!\n\n"; cvNamedWindow("RePlayR",1); cvShowImage("RePlayR",showR); cvWaitKey(500); } else { //找到标定板角点时 cout<<"第"<<aR<<"帧图像成功获得"<<countR<<"个角点...\n"; fout<<"第"<<aR<<"帧图像成功获得"<<countR<<"个角点...\n"; cvNamedWindow("RePlayR",1); IplImage * gray_imageR= cvCreateImage(cvGetSize(showR),8,1); cvCvtColor(showR,gray_imageR,CV_BGR2GRAY); cout<<"获取源图像灰度图过程完成...\n"; fout<<"获取源图像灰度图过程完成...\n"; cvFindCornerSubPix(gray_imageR,image_pointsR_bufR,countR,cvSize(11,11),cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1)); cout<<"灰度图亚像素化过程完成...\n"; fout<<"灰度图亚像素化过程完成...\n"; cvDrawChessboardCorners(showR,board_sizeR,image_pointsR_bufR,countR,foundR); cout<<"在源图像上绘制角点过程完成...\n\n"; fout<<"在源图像上绘制角点过程完成...\n\n"; cvShowImage("RePlayR",showR); cvWaitKey(500); } if(total_per_imageR==countR) { stepR=successesR*total_per_imageR; //计算存储相应坐标数据的步长 for(int i=stepR,j=0;j<total_per_imageR;++i,++j) { CV_MAT_ELEM(*image_pointsR, float,i,0)=image_pointsR_bufR[j].x; CV_MAT_ELEM(*image_pointsR, float,i,1)=image_pointsR_bufR[j].y; CV_MAT_ELEM(*object_pointsR,float,i,0)=(float)((j/board_widthR)*square_lengthR); CV_MAT_ELEM(*object_pointsR,float,i,1)=(float)((j%board_widthR)*square_heightR); CV_MAT_ELEM(*object_pointsR,float,i,2)=0.0f; } CV_MAT_ELEM(*point_countRsR,int,successesR,0)=total_per_imageR; successesR++; } cout<<"hahahahh======"<<aR<<endl; fout<<"hahahahh======"<<aR<<endl; aR++; } cvReleaseImage(&showR); cvDestroyWindow("RePlayR"); cout<<"*********************************************\n"; cout<<NImagesR<<"帧图片中,标定成功的图片为"<<successesR<<"帧...\n"; cout<<NImagesR<<"帧图片中,标定失败的图片为"<<NImagesR-successesR<<"帧...\n\n"; cout<<"*********************************************\n\n"; cout<<"按任意键开始计算摄像机内参数...\n\n"; fout<<"*********************************************\n"; fout<<NImagesR<<"帧图片中,标定成功的图片为"<<successesR<<"帧...\n"; fout<<NImagesR<<"帧图片中,标定失败的图片为"<<NImagesR-successesR<<"帧...\n\n"; fout<<"*********************************************\n\n"; fout<<"按任意键开始计算摄像机内参数...\n\n"; /*CvCapture* capture1; capture1 = cvCreateCameraCapture(0);*/ IplImage * showR_colieR; showR_colieR = cvLoadImage("F:\\graduatelunwen\\opencvprojects\\june\\opecv_ransac_sift_cameraCalibration\\dinggao_wanchengban_sift_ransac\\right_43.jpg",1); CvMat * object_pointsR2R = cvCreateMat(successesR*total_per_imageR,3,CV_32FC1); CvMat * image_pointsR2R = cvCreateMat(successesR*total_per_imageR,2,CV_32FC1); CvMat * point_countRsR2R = cvCreateMat(successesR,1,CV_32SC1); for(int i=0;i<successesR*total_per_imageR;++i) { CV_MAT_ELEM(*image_pointsR2R, float,i,0)=CV_MAT_ELEM(*image_pointsR, float,i,0); CV_MAT_ELEM(*image_pointsR2R, float,i,1)=CV_MAT_ELEM(*image_pointsR, float,i,1); CV_MAT_ELEM(*object_pointsR2R,float,i,0)=CV_MAT_ELEM(*object_pointsR,float,i,0); CV_MAT_ELEM(*object_pointsR2R,float,i,1)=CV_MAT_ELEM(*object_pointsR,float,i,1); CV_MAT_ELEM(*object_pointsR2R,float,i,2)=CV_MAT_ELEM(*object_pointsR,float,i,2); } for(int i=0;i<successesR;++i) { CV_MAT_ELEM(*point_countRsR2R,int,i,0) = CV_MAT_ELEM(*point_countRsR,int,i,0); } cvReleaseMat(&object_pointsR); cvReleaseMat(&image_pointsR); cvReleaseMat(&point_countRsR); CV_MAT_ELEM(*intrinsicR_matrixR,float,0,0)=1.0f; CV_MAT_ELEM(*intrinsicR_matrixR,float,1,1)=1.0f; cvCalibrateCamera2(object_pointsR2R,image_pointsR2R,point_countRsR2R,cvGetSize(showR_colieR), intrinsicR_matrixR,distortionR_coeffsR,rotation_vectorsR,translation_vectorsR,0); cout<<"摄像机内参数矩阵为:\n"; cout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,2) <<"\n\n"; cout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,2) <<"\n\n"; cout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,2) <<"\n\n"; fout<<"摄像机内参数矩阵为:\n"; fout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,0,2) <<"\n\n"; fout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,1,2) <<"\n\n"; fout<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,0)<<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,1) <<" "<<CV_MAT_ELEM(*intrinsicR_matrixR,float,2,2) <<"\n\n"; f_right[0]=CV_MAT_ELEM(*intrinsicR_matrixR,float,0,0); f_right[1]=CV_MAT_ELEM(*intrinsicR_matrixR,float,1,1); cout<<"畸变系数矩阵为:\n"; cout<<CV_MAT_ELEM(*distortionR_coeffsR,float,0,0)<<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,1,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,2,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,3,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,4,0) <<"\n\n"; fout<<"畸变系数矩阵为:\n"; fout<<CV_MAT_ELEM(*distortionR_coeffsR,float,0,0)<<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,1,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,2,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,3,0) <<" "<<CV_MAT_ELEM(*distortionR_coeffsR,float,4,0) <<"\n\n"; cvSave("intrinsicRs.xml",intrinsicR_matrixR); cvSave("distortionR.xml",distortionR_coeffsR); cout<<"摄像机矩阵、畸变系数向量已经分别存储在名为intrinsicRs.xml、distortionR.xml文档中\n\n"; fout<<"摄像机矩阵、畸变系数向量已经分别存储在名为intrinsicRs.xml、distortionR.xml文档中\n\n"; for(int ii = 0; ii < NImagesR; ++ii) { float tranvR[3] = {0.0}; float rotvR[3] = {0.0}; for ( int i = 0; i < 3; i++) { tranvR[i] = ((float*)(translation_vectorsR->data.ptr+ii*translation_vectorsR->step))[i]; rotvR[i] = ((float*)(rotation_vectorsR->data.ptr+rotation_vectorsR->step))[i]; } cout << "第" << ii+1 << "幅图的外参数" << endl; printf("ROTATION VECTOR 旋转向量 : \n"); printf("[ %6.4f %6.4f %6.4f ] \n", rotvR[0], rotvR[1], rotvR[2]); printf("TRANSLATION VECTOR 平移向量: \n"); printf("[ %6.4f %6.4f %6.4f ] \n", tranvR[0], tranvR[1], tranvR[2]); printf("-----------------------------------------\n"); fout << "第" << ii+1 << "幅图的外参数" << endl; fout<<"ROTATION VECTOR 旋转向量 : \n"; fout<<"[ %6.4f %6.4f %6.4f ] \n"<<rotvR[0]<<" "<< rotvR[1]<<" "<< rotvR[2]<<endl; fout<<"TRANSLATION VECTOR 平移向量: \n"; fout<<"[ %6.4f %6.4f %6.4f ] \n"<< tranvR[0]<<" "<< tranvR[1]<<" "<< tranvR[2]<<endl; fout<<"-----------------------------------------\n"; } CvMat * intrinsicR=(CvMat *)cvLoad("intrinsicRs.xml"); CvMat * distortionR=(CvMat *)cvLoad("distortionR.xml"); IplImage * mapxR=cvCreateImage(cvGetSize(showR_colieR),IPL_DEPTH_32F,1); IplImage * mapyR=cvCreateImage(cvGetSize(showR_colieR),IPL_DEPTH_32F,1); cvInitUndistortMap(intrinsicR,distortionR,mapxR,mapyR); cvNamedWindow("原始图像右",1); cvNamedWindow("非畸变图像右",1); // cout<<"按‘E’键退出显示...\n\n"; /*while(showR_colieR) {*/ IplImage * cloneR=cvCloneImage(showR_colieR); cvShowImage("原始图像右",showR_colieR); cvRemap(cloneR,showR_colieR,mapxR,mapyR); cvReleaseImage(&cloneR); cvShowImage("非畸变图像右",showR_colieR); cvWaitKey(500); /*if(cvWaitKey(10)=='e') { break; }*/ /*showR_colieR=cvQueryFrame(capture1); }*/ time_t start=0,end=0; int i,j,k; int max=-1; float hh[8]; start=time(0); float para[8][9]; float h[8]; //CvCapture* cap1; //CvCapture* cap2; //Mat input11,input22; //cap1=cvCreateCameraCapture(0); //cap2=cvCreateCameraCapture(1); /*while(1) { input11=cvQueryFrame(cap1); input22=cvQueryFrame(cap2); namedWindow("Camera_1",1); imshow("Camera_1",input11); namedWindow("Camera_2",1); imshow("Camera_2",input22); */ Mat input11,input22; //Mat input11=imread("123.jpg",1); //Mat input22=imread("124.jpg",1); //Mat input11(show_colie); //Mat input22(showR_colieR); Mat input1,input2; input11=imread("left_2.jpg",1); input22=imread("right_2.jpg",1); cvtColor(input11,input1,CV_RGB2GRAY,1); cvtColor(input22,input2,CV_RGB2GRAY,1); imwrite("left_2heibei.jpg",input1); imwrite("right_2heibai.jpg",input2); SiftFeatureDetector detector; vector<KeyPoint> keypoint1,keypoint2; detector.detect(input1,keypoint1); Mat output1; drawKeypoints(input1,keypoint1,output1); imshow("sift_result1.png",output1); imwrite("sift_result1.png",output1); Mat output2; SiftDescriptorExtractor extractor; Mat descriptor1,descriptor2; BruteForceMatcher<L2<float>> matcher; vector<DMatch> matches; Mat img_matches; detector.detect(input2,keypoint2); drawKeypoints(input2,keypoint2,output2); imshow("sift_result2.png",output2); imwrite("sift_result2.png",output2); extractor.compute(input1,keypoint1,descriptor1); extractor.compute(input2,keypoint2,descriptor2); matcher.match(descriptor1,descriptor2,matches); drawMatches(input1,keypoint1,input2,keypoint2,matches,img_matches); imshow("matches",img_matches); imwrite("matches.png",img_matches); //分配空间 int pointcount=(int)matches.size(); Mat point1(pointcount,2,CV_32F); Mat point2(pointcount,2,CV_32F); //把Keypoint转换为Mat Point2f point; for (i=0;i<pointcount;i++) { point=keypoint1[matches[i].queryIdx].pt; point1.at<float>(i,0)=point.x; point1.at<float>(i,1)=point.y; point=keypoint2[matches[i].trainIdx].pt; point2.at<float>(i,0)=point.x; point2.at<float>(i,1)=point.y; } //用RANSAC方法计算F Mat m_fundamental; vector<uchar> m_ransacstatus; m_fundamental=findFundamentalMat(point1,point2,m_ransacstatus,FM_RANSAC); /* float hhh[9]; for(i=0;i<9;i++) hhh[i]=0; for(i=0;i<3;i++) { for (j=0;j<3;j++) { hhh[i*3+j]=m_fundamental.ptr<float>(i)[j]; } } */ //计算外点个数 int outlinercount=0; for(i=0;i<pointcount;i++) { if(m_ransacstatus[i]==0)//动态为0表示外点 { outlinercount++; } } //计算内点 vector<Point2f> m_leftinliner; vector<Point2f> m_rightinliner; vector<DMatch> m_inlinermatches; //上面三个变量用于保存内点和匹配关系 int inlinercount=pointcount-outlinercount; m_inlinermatches.resize(inlinercount); m_leftinliner.resize(inlinercount); m_rightinliner.resize(inlinercount); inlinercount=0; for(i=0;i<pointcount;i++) { if(m_ransacstatus[i]!=0) { m_leftinliner[inlinercount].x=point1.at<float>(i,0); m_leftinliner[inlinercount].y=point1.at<float>(i,1); m_rightinliner[inlinercount].x=point2.at<float>(i,0); m_rightinliner[inlinercount].y=point2.at<float>(i,1); m_inlinermatches[inlinercount].queryIdx=inlinercount; m_inlinermatches[inlinercount].trainIdx=inlinercount; inlinercount++; } } //把内点转换为drawMatches可以使用的格式 vector<KeyPoint> key1(inlinercount); vector<KeyPoint> key2(inlinercount); KeyPoint::convert(m_leftinliner,key1); KeyPoint::convert(m_rightinliner,key2); //显示计算F过后的内点匹配 Mat outimage; drawMatches(input11,key1,input22,key2,m_inlinermatches,outimage); // namedWindow("Match features"); imshow("Match feature",outimage); imwrite("提纯后的.jpg",outimage); vector<KeyPoint> ransac1,ransac2; vector<KeyPoint> left,right; vector<int> tichunyihou; int counter=0; int counterdidi=0; srand(unsigned(time(0))); int counterwo; int *countergege; countergege=new int[inlinercount]; int * zuizhong=new int[inlinercount]; for(i=0;i<inlinercount;i++) { zuizhong[i]=0; } left.clear(); right.clear(); while(counter<250) { counterwo=0; for(i=0;i<inlinercount;i++) { countergege[i]=0; } counterdidi++; ransac1.clear(); ransac2.clear(); int temp[4]; for (i=0;i<4;i++) temp[i]=rand()%inlinercount; int gibal=0; for (i=0;i<3;i++) { for (j=i+1;j<4;j++) { if (temp[i]==temp[j]) { gibal=1; break; } } } if(gibal==1) continue; int a,b; float tan1=0,tan2=0; for(i=0;i<3;i++) { j=i+1; a=(j-1+4)%4; b=(j+1+4)%4; tan1=(key1[m_inlinermatches[j].queryIdx].pt.y-key1[m_inlinermatches[a].queryIdx].pt.y) /(key1[m_inlinermatches[j].queryIdx].pt.x-key1[m_inlinermatches[a].queryIdx].pt.x); tan2=(key1[m_inlinermatches[j].queryIdx].pt.y-key1[m_inlinermatches[b].queryIdx].pt.y) /(key1[m_inlinermatches[j].queryIdx].pt.x-key1[m_inlinermatches[b].queryIdx].pt.x); if(abs(tan1/tan2-1)<=0.05) gibal=2; } if (gibal==2) continue; for (i=0;i<4;i++) { cout<<temp[i]<<" "; fout<<temp[i]<<" "; } cout<<endl; fout<<endl; if(gibal==1) continue; for(j=0;j<4;j++) { ransac1.push_back(key1[m_inlinermatches[temp[j]].queryIdx]); ransac2.push_back(key2[m_inlinermatches[temp[j]].trainIdx]); } if(ransac1.empty() || ransac2.empty()) { cout<<"随机抽出四个特征点匹配对失败,请重试"<<endl; fout<<"随机抽出四个特征点匹配对失败,请重试"<<endl; continue; } //求透视矩阵 for(i=0;i<8;i++) h[i]=0.0; for (i=0;i<=7;i++) { for (j=0;j<=8;j++) { para[i][j]=0; } } for (i=0;i<=2;i++) { para[i][2]=1; para[i+3][5]=1; para[i][0]=ransac1[i].pt.x; para[i][1]=ransac1[i].pt.y; para[i+3][3]=ransac1[i].pt.x; para[i+3][4]=ransac1[i].pt.y; para[i][6]=-ransac1[i].pt.x*ransac2[i].pt.x; para[i][7]=-ransac1[i].pt.y*ransac2[i].pt.x; para[i][8]=ransac2[i].pt.x; para[i+3][6]=-ransac1[i].pt.x*ransac2[i].pt.y; para[i+3][7]=-ransac1[i].pt.y*ransac2[i].pt.y; para[i+3][8]=ransac2[i].pt.y; } para[6][2]=1; para[7][5]=1; para[6][0]=ransac1[3].pt.x; para[6][1]=ransac1[3].pt.y; para[7][3]=ransac1[3].pt.x; para[7][4]=ransac1[3].pt.y; para[6][6]=-ransac1[3].pt.x*ransac2[3].pt.y; para[6][7]=-ransac1[3].pt.y*ransac2[3].pt.x; para[6][8]=ransac2[3].pt.x; para[7][6]=-ransac1[3].pt.x*ransac2[3].pt.y; para[7][7]=-ransac1[3].pt.y*ransac2[3].pt.y; para[7][8]=ransac2[3].pt.y; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //建立完扩展矩阵,求出透视矩阵的参数:透视矩阵参数估值 for (int g=0;g<8;g++)//初始化 h[g]=0.0; for (i=0;i<8;i++) { float temper1=para[i][i]; if (para[i][i]!=0) { for (int j=i+1;j<8;j++) { float temper2=para[j][i]; if (para[j][i]!=0) { for (int k=i;k<9;k++) { para[j][k]=para[i][k]-para[j][k]*para[i][i]/temper2; } } else continue; } for (int r=i;r<9;r++) para[i][r]/=temper1; } else continue; } for (i=0;i<=7;i++) h[i]=para[i][8]; for (j=7;j>=0;j--) { for (int k=0;k<7-j;k++) { h[j]-=h[7-k]*para[j][7-k]; } } //计算出每个透视矩阵所满足的内点数 float xx,yy; float juli; int ok=0; for(i=0;i<inlinercount;i++) { xx=0;yy=0; xx=h[0]*key1[m_inlinermatches[i].queryIdx].pt.x+h[1]*key1[m_inlinermatches[i].queryIdx].pt.y+h[2]; yy=h[3]*key1[m_inlinermatches[i].queryIdx].pt.x+h[4]*key1[m_inlinermatches[i].queryIdx].pt.y+h[5]; juli=sqrt(pow((xx-key2[m_inlinermatches[i].trainIdx].pt.x),2)+pow((yy-key2[m_inlinermatches[i].trainIdx].pt.y),2)); if (juli<2) { countergege[counterwo]=i; counterwo++; ok++; } } if(ok>max) { max=ok; for(k=0;k<8;k++) hh[k]=h[k]; for(i=0;i<inlinercount;i++) { zuizhong[i]=countergege[i]; } } counter++; } for(i=0;i<8;i++) { cout<<hh[i]<<endl; fout<<hh[i]<<endl; } for(i=0;i<max;i++) { left.push_back(key1[m_inlinermatches[zuizhong[i]].queryIdx]); right.push_back(key2[m_inlinermatches[zuizhong[i]].trainIdx]); } cout<<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"<<endl; vector<DMatch> wanquantichun; int haha=left.size(); wanquantichun.resize(haha); for(i=0;i<haha;i++) { wanquantichun[i].queryIdx=i; wanquantichun[i].trainIdx=i; } Mat outimagehaha; float f=85; float T=2000; drawMatches(input11,left,input22,right,wanquantichun,outimagehaha); float xl=0,xr=0; float Z=430; for(i=0;i<haha;i++) { Z=0; if(key1[i].pt.x<428 && key1[i].pt.x>213 ) { if(key2[i].pt.x<428 && key2[i].pt.x>213) { xl=abs(385-key1[i].pt.x); xr=abs(282-key2[i].pt.x); Z=abs(f*T/(xl+xr)); cout<<"距离为=="<<Z<<endl; fout<<"距离为=="<<Z<<endl; } } } // namedWindow("Match features"); /*for(i=0;i<haha;i++) { if(left[i].pt.x<640 && left[i].pt.x>385 ) { if(right[i].pt.x<282 && right[i].pt.x>0 ) { xl=abs(385-key1[i].pt.x); xr=abs(282-key2[i].pt.x); //Z=abs(f*T/(xl-xr)); f=abs(Z*(xl+xr)/T); cout<<"距离为=="<<f<<endl; fout<<"距离为=="<<f<<endl; } } } */ imshow("完全提纯后 Match feature",outimagehaha); imwrite("完全提纯后的.jpg",outimagehaha); float uxleft,uxright; //uxleft= //图像配准 int xx1=input11.cols; int yy1=input11.rows; int xx2=input22.cols; int yy2=input22.rows; int garo=0; int saero=0; int yiweiX=1000,yiweiYmin=1000,yiweiYmax=-1000; int xxx,yyy; for(i=0;i<yy1;i++) { for (j=0;j<xx1;j++) { garo=int(j*hh[0]+i*hh[1]+hh[2]); saero=int(j*hh[3]+i*hh[4]+hh[5]); if(yiweiX>garo) yiweiX=garo; if(yiweiYmin>saero) yiweiYmin=saero; if(yiweiYmax<saero) yiweiYmax=saero; } } if(yiweiX>0) yiweiX=0; cout<<yiweiYmin<<" "<<yiweiX<<" "<<yiweiYmax<<endl; fout<<yiweiYmin<<" "<<yiweiX<<" "<<yiweiYmax<<endl; if(yiweiYmax>=yy2) { //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1111111111111111111111111 if(yiweiYmin<0) { cout<<"第一种情况"<<endl; fout<<"第一种情况"<<endl; Mat zuihoupeizhun(yiweiYmax-yiweiYmin,xx2-yiweiX,CV_8UC3,Scalar(0,0,0)); for(i=0;i<yy1;i++) { for(j=0;j<xx1;j++) { garo=int(j*hh[0]+i*hh[1]+hh[2]); saero=int(j*hh[3]+i*hh[4]+hh[5]); xxx=garo-yiweiX; yyy=saero-yiweiYmin; if (yyy>=0 && xxx>=0&&xxx<(xx2-yiweiX)&&yyy<(yiweiYmax-yiweiYmin)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input11.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input11.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input11.at<Vec3b>(i,j)[2]; } else continue; } } for (i=0;i<yy2;i++) { for (j=0;j<xx2;j++) { xxx=j-yiweiX; yyy=i-yiweiYmin; if (yyy>=0 && xxx>=0&&xxx<(xx2-yiweiX)&&yyy<(yiweiYmax-yiweiYmin)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input22.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input22.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input22.at<Vec3b>(i,j)[2]; } else continue; } } namedWindow("src"); imshow("src",zuihoupeizhun); imwrite("src.png",zuihoupeizhun); } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^222222222222222 else { cout<<"第二种情况"<<endl; fout<<"第二种情况"<<endl; Mat zuihoupeizhun(yiweiYmax,xx2-yiweiX,CV_8UC3,Scalar(0,0,0)); for(i=0;i<yy1;i++) { for(j=0;j<xx1;j++) { garo=int(j*hh[0]+i*hh[1]+hh[2]); saero=int(j*hh[3]+i*hh[4]+hh[5]); xxx=garo-yiweiX; yyy=saero; if (yyy>=0 && xxx>=0 && yyy<yiweiYmax && xxx<(xx2-yiweiX)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input11.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input11.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input11.at<Vec3b>(i,j)[2]; } else continue; } } for (i=0;i<yy2;i++) { for (j=0;j<xx2;j++) { xxx=j-yiweiX; yyy=i; if (yyy>=0 && xxx>=0 && yyy<yiweiYmax && xxx<(xx2-yiweiX)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input22.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input22.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input22.at<Vec3b>(i,j)[2]; } else continue; } } namedWindow("src"); imshow("src",zuihoupeizhun); imwrite("src.png",zuihoupeizhun); } } else { //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^3333333333333333333333333333 if(yiweiYmin<0) { cout<<"第三种情况"<<endl; fout<<"第三种情况"<<endl; Mat zuihoupeizhun(yy2-yiweiYmin,xx2-yiweiX,CV_8UC3,Scalar(0,0,0)); for(i=0;i<yy1;i++) { for(j=0;j<xx1;j++) { garo=int(j*hh[0]+i*hh[1]+hh[2]); saero=int(j*hh[3]+i*hh[4]+hh[5]); xxx=garo-yiweiX; yyy=saero-yiweiYmin; if (yyy>=0 && xxx>=0 && yyy<(yy2-yiweiYmin) && xxx<(xx2-yiweiX)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input11.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input11.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input11.at<Vec3b>(i,j)[2]; } else continue; } } for (i=0;i<yy2;i++) { for (j=0;j<xx2;j++) { xxx=j-yiweiX; yyy=i-yiweiYmin; if (yyy>=0 && xxx>=0 && yyy<(yy2-yiweiYmin) && xxx<(xx2-yiweiX)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input22.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input22.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input22.at<Vec3b>(i,j)[2]; } else continue; } } namedWindow("src"); imshow("src",zuihoupeizhun); imwrite("src.png",zuihoupeizhun); } else { //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^444444444444444444 cout<<"第四种情况"<<endl; fout<<"第四种情况"<<endl; Mat zuihoupeizhun(yy2,xx2-yiweiX,CV_8UC3,Scalar(0,0,0)); for(i=0;i<yy1;i++) { for(j=0;j<xx1;j++) { garo=int(j*hh[0]+i*hh[1]+hh[2]); saero=int(j*hh[3]+i*hh[4]+hh[5]); xxx=garo-yiweiX; yyy=saero; if (yyy>=0 && xxx>=0 && yyy<yy2 && xxx<(xx2-yiweiX)) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input11.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input11.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input11.at<Vec3b>(i,j)[2]; } else continue; } } for (i=0;i<yy2;i++) { for (j=0;j<xx2;j++) { xxx=j-yiweiX; yyy=i; if (xxx>=0 && yyy>=0) { zuihoupeizhun.at<Vec3b>(yyy,xxx)[0]=input22.at<Vec3b>(i,j)[0]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[1]=input22.at<Vec3b>(i,j)[1]; zuihoupeizhun.at<Vec3b>(yyy,xxx)[2]=input22.at<Vec3b>(i,j)[2]; } else continue; } } namedWindow("src"); imshow("src",zuihoupeizhun); imwrite("src.jpg",zuihoupeizhun); } } end=time(0); cout<<"i love you"<<endl; fout<<"i love you"<<endl; cout<<"最后的max===="<<max<<endl; fout<<"最后的max===="<<max<<endl; end=time(0); cout<<endl<<"总跑程序的时间为:"<<end-start<<"秒"<<endl; fout<<endl<<"总跑程序的时间为:"<<end-start<<"秒"<<endl; cout<<endl;fout<<endl; cout<<"counter=="<<counter<<endl<<"counterdidi=="<<counterdidi<<endl; fout<<"counter=="<<counter<<endl<<"counterdidi=="<<counterdidi<<endl; waitKey(30000); }