caliber.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // Created by zx on 22-11-1.
  3. //
  4. #include <opencv2/imgproc/types_c.h>
  5. #include<opencv2/opencv.hpp>
  6. #include<iostream>
  7. using namespace cv;
  8. using namespace std;
  9. cv::Mat undistored_image(cv::Mat image,Mat cameraMatrix, Mat distCoeffs)
  10. {
  11. int rows = image.rows, cols = image.cols;
  12. cv::Mat image_undistort = cv::Mat(rows, cols, CV_8UC1); // 去畸变以后的图
  13. double cx=cameraMatrix.at<double>(0,2);
  14. double cy=cameraMatrix.at<double>(1,2);
  15. double fx=cameraMatrix.at<double>(0,0);
  16. double fy=cameraMatrix.at<double>(1,1);
  17. double k1=distCoeffs.at<double>(0,0);
  18. double k2=distCoeffs.at<double>(0,1);
  19. double p1=distCoeffs.at<double>(0,2);
  20. double p2=distCoeffs.at<double>(0,3);
  21. double k3=distCoeffs.at<double>(0,4);
  22. // 计算去畸变后图像的内容
  23. for (int v = 0; v < rows; v++) {
  24. for (int u = 0; u < cols; u++) {
  25. // 按照公式,计算点(u,v)对应到畸变图像中的坐标(u_distorted, v_distorted)
  26. double x = (u - cx) / fx, y = (v - cy) / fy;
  27. double r = sqrt(x * x + y * y);
  28. double x_distorted = x * (1 + k1 * r * r + k2 * r * r * r * r+k3 *r*r* r * r * r * r) + 2 * p1 * x * y + p2 * (r * r + 2 * x * x);
  29. double y_distorted = y * (1 + k1 * r * r + k2 * r * r * r * r+k3 *r*r* r * r * r * r) + p1 * (r * r + 2 * y * y) + 2 * p2 * x * y;
  30. double u_distorted = fx * x_distorted + cx;
  31. double v_distorted = fy * y_distorted + cy;
  32. // 赋值 (最近邻插值)
  33. if (u_distorted >= 0 && v_distorted >= 0 && u_distorted < cols && v_distorted < rows) {
  34. image_undistort.at<uchar>(v, u) = image.at<uchar>((int) v_distorted, (int) u_distorted);
  35. } else {
  36. image_undistort.at<uchar>(v, u) = 0;
  37. }
  38. }
  39. }
  40. return image_undistort;
  41. }
  42. Mat image, img_gray;
  43. int BOARDSIZE[2]{ 8,11 };//棋盘格每行每列角点个数
  44. int main()
  45. {
  46. vector<vector<Point3f>> objpoints_img;//保存棋盘格上角点的三维坐标
  47. vector<Point3f> obj_world_pts;//三维世界坐标
  48. vector<vector<Point2f>> images_points;//保存所有角点
  49. vector<Point2f> img_corner_points;//保存每张图检测到的角点
  50. vector<String> images_path;//创建容器存放读取图像路径
  51. string image_path = "/home/zx/doc/private_hub/triangle/images/标定数据/上方/all/*.bmp";//待处理图路径
  52. glob(image_path, images_path);//读取指定文件夹下图像
  53. //转世界坐标系
  54. for (int i = 0; i < BOARDSIZE[1]; i++)
  55. {
  56. for (int j = 0; j < BOARDSIZE[0]; j++)
  57. {
  58. obj_world_pts.push_back(Point3f(j, i, 0));
  59. }
  60. }
  61. for (int i = 0; i < images_path.size(); i++)
  62. {
  63. image = imread(images_path[i],0);
  64. img_gray=image;
  65. //cvtColor(image, img_gray, COLOR_BGR2GRAY);
  66. //检测角点
  67. bool found_success = findChessboardCorners(img_gray, Size(BOARDSIZE[0], BOARDSIZE[1]),
  68. img_corner_points,
  69. CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
  70. //显示角点
  71. if (found_success)
  72. {
  73. //迭代终止条件
  74. TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.001);
  75. //进一步提取亚像素角点
  76. cornerSubPix(img_gray, img_corner_points, Size(11, 11),
  77. Size(-1, -1), criteria);
  78. //绘制角点
  79. drawChessboardCorners(image, Size(BOARDSIZE[0], BOARDSIZE[1]), img_corner_points,
  80. found_success);
  81. objpoints_img.push_back(obj_world_pts);//从世界坐标系到相机坐标系
  82. images_points.push_back(img_corner_points);
  83. }
  84. //char *output = "image";
  85. char text[] = "image";
  86. char *output = text;
  87. //imshow(output, image);
  88. // waitKey(0);
  89. }
  90. /*
  91. 计算内参和畸变系数等
  92. */
  93. Mat cameraMatrix, distCoeffs, R, T;//内参矩阵,畸变系数,旋转量,偏移量
  94. calibrateCamera(objpoints_img, images_points, img_gray.size(),
  95. cameraMatrix, distCoeffs, R, T);
  96. cout << "cameraMatrix:" << endl;
  97. cout << cameraMatrix << endl;
  98. cout << "*****************************" << endl;
  99. cout << "distCoeffs:" << endl;
  100. cout << distCoeffs << endl;
  101. cout << "*****************************" << endl;
  102. cout << "Rotation vector:" << endl;
  103. cout << R << endl;
  104. cout << "*****************************" << endl;
  105. cout << "Translation vector:" << endl;
  106. cout << T << endl;
  107. FileStorage fwrite("../cfg/cameraMatrix.yaml", FileStorage::WRITE);
  108. //存入矩阵Mat类型的数据
  109. fwrite.write("cameraMatrix", cameraMatrix);
  110. fwrite.write("distCoeffs", distCoeffs);
  111. ///*
  112. //畸变图像校准
  113. //*/
  114. Mat src, dst;
  115. src = imread("/home/zx/doc/private_hub/triangle/images/标定数据/上方/all/down_1.bmp",0); //读取校正前图像
  116. undistort(src, dst, cameraMatrix, distCoeffs);
  117. char texts[] = "image_dst";
  118. char *dst_output = texts;
  119. //char *dst_output = "image_dst";
  120. imshow(dst_output, dst);
  121. waitKey(100);
  122. imwrite("/home/zx/doc/private_hub/triangle/images/undistored.bmp", dst); //校正后图像
  123. cv::Mat undist=undistored_image(src,cameraMatrix,distCoeffs);
  124. imwrite("/home/zx/doc/private_hub/triangle/images/undistored_1.bmp", undist); //校正后图像
  125. cv::Mat diff=undist-dst;
  126. imwrite("/home/zx/doc/private_hub/triangle/images/diff.bmp", diff); //
  127. destroyAllWindows();//销毁显示窗口
  128. return 0;
  129. }