Based on MATLAB calibration data, using OPENCV to realize the calibration of Binocular Stereo camera (source code)

Source: Internet
Author: User
Tags assert sprintf

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" >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.