I have benefited from this blog from Daniel:
http://blog.csdn.net/sunanger_wang/article/details/7744025
http://www.opencv.org.cn/forum.php?mod=viewthread&tid=12963
http://blog.csdn.net/scyscyao/article/details/5562024
http://blog.csdn.net/chenyusiyuan/article/details/5967291
The last three consecutive articles were introduced in detail, very good.
Because there are no answers to some of the questions below, those are details, but you know that sometimes it's a little bit of an hour to get stuck.
No good explanation also no source code and sample diagram to the quick, the younger brother put the content of these days groping.
My platform: 2 Logitech C170 Cameras
Hey.. Relatively humble
Matlab calibration:
Believe that carefully read the principle and the above blog can use MATLAB to calculate the results of binocular, here is a point to note, is to calculate the binocular parameters, left and right two cameras must simultaneously shoot the checkerboard, altogether 20. I was a solo shooting, and later found that single-purpose data can be calibrated, binocular will be error, think of the principle is also, binocular calibration must be shot at the same time. This is a piece of code that you write and capture the image at the same time, press C, and you can save the image.
#include <opencv2/opencv.hpp> #include <iostream> using namespace std;
int pic_num = 13;
char* name_l = (char*) malloc (sizeof (char) *200);
char* Name_r = (char*) malloc (sizeof (char) *200);
int main () {cout << "test two cameras simultaneously read data" << Endl;
Cvcapture* Cap_left;
Cvcapture* Cap_right;
Iplimage *img0, *IMG1;
Iplimage *img_left, *img_right;
Iplimage *img_left_change, *img_right_change;
Cvnamedwindow ("Camera_left");
Cvnamedwindow ("Camera_right");
Cap_left = cvcreatecameracapture (1);
ASSERT (Cap_left! = NULL);
Cap_right = cvcreatecameracapture (0);
ASSERT (Cap_right! = NULL);
while (1) {cvgrabframe (cap_left);
Cvgrabframe (Cap_right);
Img0 = Cvretrieveframe (cap_left);//img0 1 is just a pointer, which can be refreshed in a separate mining thread img1 = cvretrieveframe (cap_right);
if (!img0 | |!img1) {cout << "camera0 error" << Endl;
Break
} img_left = Cvcloneimage (IMG0);
Img_right = Cvcloneimage (IMG1); Cvshowimage ("Camera_Left ", img_left);
Cvshowimage ("Camera_right", img_right);
char C = cvwaitkey (33);
if (c = =) break;
if (c = = ' C ') {sprintf (name_l, "leftpic%d.jpg", pic_num);
sprintf (Name_r, "rightpic%d.jpg", pic_num);
pic_num++;
Cvsaveimage (name_l, img_left);
Cvsaveimage (Name_r, img_right);
} cvreleaseimage (&img_left);
Cvreleaseimage (&img_right);
} cvreleasecapture (&cap_left);
Cvreleasecapture (&cap_right);
Cvdestroywindow ("Camera_left");
Cvdestroywindow ("Camera_right");
return 0; }
By the way, in the Loop Cvreleaseimage (&img_left), Cvreleaseimage (&img_right), must be executed, or a memory leak will occur. If you don't believe it, open the resource manager and comment out that the program runs when you see that the memory is rising.
OpenCV to play:
Since most people recommend using a MATLAB calibration box, the next step is to store the calibrated data in an XML file. The XML does not understand, please own Baidu.
Since some people have been asking how to write files, I'll post all the files I want to write myself:
Intrinsics_camera_left.xml:
<?xml version= "1.0"?>
<opencv_storage>
<intrinsics_camera_left type_id= "Opencv-matrix" >
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
690.09102 0. 325.38988
0. 686.25294 286.9196
0. 0. 1.
</data>
</Intrinsics_Camera_Left>
</opencv_storage>
Intrinsics_camera_right.xml:
<?xml version= "1.0"?>
<opencv_storage>
<intrinsics_camera_right type_id= "Opencv-matrix" >
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
691.94410 0. 342.74569
0. 685.94161 231.16984
0. 0. 1.
</data>
</Intrinsics_Camera_Right>
</opencv_storage>
Distortion_camera_left.xml:
<?xml version= "1.0"?>
<opencv_storage>
<distortion type_id= "Opencv-matrix" >
<rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
-0.02240 -0.05900 0.00894 -0.00590 0.00000
</data>
</Distortion>
</opencv_storage>
Distortion_camera_right.xml:
<?xml version= "1.0"?>
<opencv_storage>
<distortion type_id= "Opencv-matrix" >
< rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
0.05543 -0.29862 -0.00669 0.01307 0.00000
</data>
</Distortion>
</ Opencv_storage>
Translation.xml
<?xml version= "1.0"?>
<opencv_storage>
<translation type_id= "Opencv-matrix" >
<rows>3</rows>
<cols>1</cols>
<dt>d</dt>
<data>
-194.10083 6.39147 -11.45062
</data>
</Translation>
</opencv_storage >
Rotrodrigues.xml
<?xml version= "1.0"?>
<opencv_storage>
<rotrodrigues type_id= "Opencv-matrix" >
< rows>3</rows>
<cols>1</cols>
<dt>d</dt>
<data>
-0.06416 -0.11879 -0.07601
</data>
</RotRodrigues>
</opencv_storage>
Save these separately, the contents of which are written in accordance with the results of MATLAB.
The next step is stereo image correction. Specific principles please see the previous blog, very detailed.
Little brother here just put the code, so that you can better understand:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std;
int main () {cout << "test two cameras simultaneously read data" << Endl;
Read internal parameters Cvmat *intrinsics_camera_left = (Cvmat *) cvload ("Intrinsics_camera_left.xml");
Cvmat *intrinsics_camera_right = (Cvmat *) cvload ("Intrinsics_camera_right.xml");
Cvmat *distortion_camera_left = (Cvmat *) cvload ("Distortion_camera_left.xml");
Cvmat *distortion_camera_right = (Cvmat *) cvload ("Distortion_camera_right.xml");
Cvmat *translation_matlab = (Cvmat *) cvload ("Translation.xml");
Cvmat *rotrodrigues_matlab = (Cvmat *) cvload ("Rotrodrigues.xml");
Cvmat *R_OPENCV = Cvcreatemat (3, 3, cv_64f);
CvRodrigues2 (Rotrodrigues_matlab, R_OPENCV);
Create a mapping matrix iplimage *left_mapx = Cvcreateimage (Cvsize (640,480), ipl_depth_32f, 1);
Iplimage *left_mapy = Cvcreateimage (Cvsize (640,480), ipl_depth_32f, 1);
Iplimage *right_mapx = Cvcreateimage (Cvsize (640,480), ipl_depth_32f, 1); Iplimage *right_mapy = Cvcreateimage (Cvsize (640, 480), ipl_depth_32f, 1);
Cvmat *RL = Cvcreatemat (3, 3, cv_64f);
Cvmat *RR = Cvcreatemat (3, 3, cv_64f);
Cvmat *PL = Cvcreatemat (3, 4, cv_64f);
Cvmat *PR = Cvcreatemat (3, 4, cv_64f); Cvstereorectify (Intrinsics_camera_left, intrinsics_camera_right, \ Distortion_camera_left, Distortion_Came
Ra_right, \ Cvsize (640, 480), R_OPENCV, Translation_matlab, \ Rl, Rr, Pl, Pr); Cvstereorectify (Intrinsics_camera_left, intrinsics_camera_right, \ Distortion_camera_left, Distortion_Camera_Right , \ Cvsize (640, 480), R_OPENCV, Translation_matlab, \ Rl, Rr, Pl, Pr, 0, 1024, 0);//Increase image scaling, remove dead zone cvinitundistortrecti
Fymap (Intrinsics_camera_left, Distortion_camera_left, Rl, Pl, \ left_mapx, left_mapy); Cvinitundistortrectifymap (Intrinsics_camera_right, Distortion_camera_right, Rr, Pr, \ right_mapx,
Right_mapy);
Cvcapture* Cap_left;
Cvcapture* Cap_right;
Iplimage *img0, *IMG1;
Iplimage *img_left, *img_right; IPlimage *img_left_change, *img_right_change;
Cvnamedwindow ("Camera_left");
Cvnamedwindow ("Camera_right");
Cap_left = cvcreatecameracapture (1);
ASSERT (Cap_left! = NULL);
Cap_right = cvcreatecameracapture (0);
ASSERT (Cap_right! = NULL);
while (1) {cvgrabframe (cap_left);
Cvgrabframe (Cap_right);
Img0 = Cvretrieveframe (cap_left);
IMG1 = Cvretrieveframe (cap_right);
if (!img0 | |!img1) {cout << "camera0 error" << Endl;
Break
} img_left = Cvcloneimage (IMG0);
Img_right = Cvcloneimage (IMG1);
Img_left_change = Cvcloneimage (IMG0);
Img_right_change = Cvcloneimage (IMG1);
Cvremap (Img_left, Img_left_change, LEFT_MAPX, left_mapy);
Cvremap (Img_right, Img_right_change, RIGHT_MAPX, right_mapy);
Cvline (Img_left_change, Cvpoint (0,48), Cvpoint (640-1), cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*2), Cvpoint (640-1, 48*2), Cvscalar (255, 0, 0)); Cvline (Img_left_change, Cvpoint (0,48*3), Cvpoint (640-1, 48*3), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*4), Cvpoint (640-1, 48*4), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*5), Cvpoint (640-1, 48*5), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*6), Cvpoint (640-1, 48*6), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*7), Cvpoint (640-1, 48*7), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*8), Cvpoint (640-1, 48*8), Cvscalar (255, 0, 0));
Cvline (Img_left_change, Cvpoint (0,48*9), Cvpoint (640-1, 48*9), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48), Cvpoint (640-1), cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*2), Cvpoint (640-1, 48*2), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*3), Cvpoint (640-1, 48*3), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*4), Cvpoint (640-1, 48*4), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*5), Cvpoint (640-1, 48*5), Cvscalar (255, 0, 0)); Cvline (Img_rigHt_change, Cvpoint (0,48*6), Cvpoint (640-1, 48*6), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*7), Cvpoint (640-1, 48*7), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*8), Cvpoint (640-1, 48*8), Cvscalar (255, 0, 0));
Cvline (Img_right_change, Cvpoint (0,48*9), Cvpoint (640-1, 48*9), Cvscalar (255, 0, 0));
Cvshowimage ("Camera_left", img_left);
Cvshowimage ("Camera_right", img_right);
Cvshowimage ("Camera_left_change", Img_left_change);
Cvshowimage ("Camera_right_change", Img_right_change);
char C = cvwaitkey (33);
if (c = =) break;
Cvreleaseimage (&img_left);
Cvreleaseimage (&img_right);
Cvreleaseimage (&img_left_change);
Cvreleaseimage (&img_right_change);
} cvreleasecapture (&cap_left);
Cvreleasecapture (&cap_right);
Cvdestroywindow ("Camera_left");
Cvdestroywindow ("Camera_right");
return 0; }
Cvstereorectify can be added at the end of the parameter to remove the black dead zone.
Some blogs mention that the displacement vectors are negative and are modified to be positive, such as I'm <pre name= "code" class= "HTML" >-194.10083 6.39147-11.45062
The first item to change to 194.10083, I do not understand, the program is not modified, but the results are correct.
Finally, thank you again for the above mentioned bloggers.
</pre><pre name= "code" class= "CPP" >