Interpolator.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. //
  2. // Created by zx on 22-12-18.
  3. //
  4. #include "Interpolator.h"
  5. Interpolator::Interpolator(){}
  6. void Interpolator::AddImage(cv::Mat src,double distance)
  7. {
  8. CSteger steger;
  9. cv::Mat image = src(cv::Rect(0, 0, src.cols, src.rows)).clone();
  10. for (int i = 0; i < image.rows; i++)
  11. {
  12. for (int j = 0; j < image.cols; j++)
  13. {
  14. if (image.at<uchar>(i, j) < 150)
  15. image.at<uchar>(i, j) = 0;
  16. }
  17. }
  18. cv::GaussianBlur(image, image, cv::Size(3, 3), 3, 3);
  19. std::vector<cv::Point2d> points = steger.StripCenter(image);
  20. for(int i=0;i<points.size();++i)
  21. {
  22. CalibPoint pt;
  23. pt.x=points[i].x;
  24. pt.y=points[i].y;
  25. pt.z=distance;
  26. samples_.push_back(pt);
  27. }
  28. }
  29. cv::Mat Interpolator::Calib3()
  30. {
  31. cv::Mat A=cv::Mat::zeros(samples_.size(),10,CV_64FC1);
  32. cv::Mat B=cv::Mat::zeros(samples_.size(),1,CV_64FC1);
  33. for(int i=0;i<samples_.size();++i)
  34. {
  35. CalibPoint pt=samples_[i];
  36. double x=pt.x/1000.0;
  37. double y=pt.y/1000.0;
  38. double z=pt.z;
  39. A.at<double>(i,0)=pow(x,3);
  40. A.at<double>(i,1)=pow(y,3);
  41. A.at<double>(i,2)=x*x*y;
  42. A.at<double>(i,3)=x*y*y;
  43. A.at<double>(i,4)=x*x;
  44. A.at<double>(i,5)=y*y;
  45. A.at<double>(i,6)=x*y;
  46. A.at<double>(i,7)=x;
  47. A.at<double>(i,8)=y;
  48. A.at<double>(i,9)=1;
  49. B.at<double>(i,0)=z;
  50. }
  51. cv::Mat P=(A.t()*A).inv()*A.t()*B;
  52. return P;
  53. }
  54. cv::Mat Interpolator::Calib4()
  55. {
  56. cv::Mat A=cv::Mat::zeros(samples_.size(),15,CV_64FC1);
  57. cv::Mat B=cv::Mat::zeros(samples_.size(),1,CV_64FC1);
  58. for(int i=0;i<samples_.size();++i)
  59. {
  60. CalibPoint pt=samples_[i];
  61. double x=pt.x/1000.0;
  62. double y=pt.y/1000.0;
  63. double z=pt.z;
  64. A.at<double>(i,0)=pow(x,4);
  65. A.at<double>(i,1)=pow(y,4);
  66. A.at<double>(i,2)=x*x*x*y;
  67. A.at<double>(i,3)=x*x*y*y;
  68. A.at<double>(i,4)=x*y*y*y;
  69. A.at<double>(i,5)=pow(x,3);
  70. A.at<double>(i,6)=pow(y,3);
  71. A.at<double>(i,7)=x*x*y;
  72. A.at<double>(i,8)=x*y*y;
  73. A.at<double>(i,9)=x*x;
  74. A.at<double>(i,10)=y*y;
  75. A.at<double>(i,11)=x*y;
  76. A.at<double>(i,12)=x;
  77. A.at<double>(i,13)=y;
  78. A.at<double>(i,14)=1;
  79. B.at<double>(i,0)=z;
  80. }
  81. cv::Mat P=(A.t()*A).inv()*A.t()*B;
  82. return P;
  83. }
  84. cv::Mat Interpolator::undistored_image(cv::Mat image,cv::Mat cameraMatrix, cv::Mat distCoeffs)
  85. {
  86. int rows = image.rows, cols = image.cols;
  87. cv::Mat image_undistort = cv::Mat(rows, cols, CV_8UC1); // 去畸变以后的图
  88. double cx=cameraMatrix.at<double>(0,2);
  89. double cy=cameraMatrix.at<double>(1,2);
  90. double fx=cameraMatrix.at<double>(0,0);
  91. double fy=cameraMatrix.at<double>(1,1);
  92. double k1=distCoeffs.at<double>(0,0);
  93. double k2=distCoeffs.at<double>(0,1);
  94. double p1=distCoeffs.at<double>(0,2);
  95. double p2=distCoeffs.at<double>(0,3);
  96. double k3=distCoeffs.at<double>(0,4);
  97. // 计算去畸变后图像的内容
  98. for (int v = 0; v < rows; v++) {
  99. for (int u = 0; u < cols; u++) {
  100. // 按照公式,计算点(u,v)对应到畸变图像中的坐标(u_distorted, v_distorted)
  101. double x = (u - cx) / fx, y = (v - cy) / fy;
  102. double r = sqrt(x * x + y * y);
  103. 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);
  104. 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;
  105. double u_distorted = fx * x_distorted + cx;
  106. double v_distorted = fy * y_distorted + cy;
  107. // 赋值 (最近邻插值)
  108. if (u_distorted >= 0 && v_distorted >= 0 && u_distorted < cols && v_distorted < rows) {
  109. image_undistort.at<uchar>(v, u) = image.at<uchar>((int) v_distorted, (int) u_distorted);
  110. } else {
  111. image_undistort.at<uchar>(v, u) = 0;
  112. }
  113. }
  114. }
  115. return image_undistort;
  116. }
  117. std::vector<cv::Point3d> Interpolator::predict3(cv::Mat src,cv::Mat cameraMatrix, cv::Mat distCoeffs,cv::Mat P)
  118. {
  119. //矫正畸变
  120. cv::Mat image_undistort=undistored_image(src,cameraMatrix,distCoeffs);
  121. CSteger steger;
  122. cv::Mat image = image_undistort(cv::Rect(0, 0, image_undistort.cols, image_undistort.rows)).clone();
  123. for (int i = 0; i < image.rows; i++)
  124. {
  125. for (int j = 0; j < image.cols; j++)
  126. {
  127. if (image.at<uchar>(i, j) < 150)
  128. image.at<uchar>(i, j) = 0;
  129. }
  130. }
  131. cv::GaussianBlur(image, image, cv::Size(3, 3), 3, 3);
  132. std::vector<cv::Point2d> points = steger.StripCenter(image);
  133. double a0=P.at<double>(0,0);
  134. double a1=P.at<double>(1,0);
  135. double a2=P.at<double>(2,0);
  136. double a3=P.at<double>(3,0);
  137. double a4=P.at<double>(4,0);
  138. double a5=P.at<double>(5,0);
  139. double a6=P.at<double>(6,0);
  140. double a7=P.at<double>(7,0);
  141. double a8=P.at<double>(8,0);
  142. double a9=P.at<double>(9,0);
  143. double cx=cameraMatrix.at<double>(0,2);
  144. double cy=cameraMatrix.at<double>(1,2);
  145. double fx=cameraMatrix.at<double>(0,0);
  146. double fy=cameraMatrix.at<double>(1,1);
  147. std::vector<cv::Point3d> pts3d;
  148. for(int i=0;i<points.size();++i)
  149. {
  150. double x=points[i].x/1000.0;
  151. double y=points[i].y/1000.0;
  152. double z=a0*pow(x,3)+a1*pow(y,3)+a2*x*x*y+a3*x*y*y+a4*x*x+a5*y*y+a6*x*y
  153. +a7*x+a8*y+a9;
  154. //计算x,y
  155. double rx=(points[i].x-cx)/fx;
  156. double ry=(points[i].y-cy)/fy;
  157. pts3d.push_back(cv::Point3d(rx,ry,z));
  158. }
  159. return pts3d;
  160. }
  161. std::vector<cv::Point3d> Interpolator::predict4(cv::Mat src,cv::Mat cameraMatrix, cv::Mat distCoeffs,cv::Mat P)
  162. {
  163. //矫正畸变
  164. cv::Mat image_undistort=undistored_image(src,cameraMatrix,distCoeffs);
  165. CSteger steger;
  166. cv::Mat image = image_undistort(cv::Rect(0, 0, image_undistort.cols, image_undistort.rows)).clone();
  167. for (int i = 0; i < image.rows; i++)
  168. {
  169. for (int j = 0; j < image.cols; j++)
  170. {
  171. if (image.at<uchar>(i, j) < 150)
  172. image.at<uchar>(i, j) = 0;
  173. }
  174. }
  175. cv::GaussianBlur(image, image, cv::Size(3, 3), 3, 3);
  176. std::vector<cv::Point2d> points = steger.StripCenter(image);
  177. double a0=P.at<double>(0,0);
  178. double a1=P.at<double>(1,0);
  179. double a2=P.at<double>(2,0);
  180. double a3=P.at<double>(3,0);
  181. double a4=P.at<double>(4,0);
  182. double a5=P.at<double>(5,0);
  183. double a6=P.at<double>(6,0);
  184. double a7=P.at<double>(7,0);
  185. double a8=P.at<double>(8,0);
  186. double a9=P.at<double>(9,0);
  187. double a10=P.at<double>(10,0);
  188. double a11=P.at<double>(11,0);
  189. double a12=P.at<double>(12,0);
  190. double a13=P.at<double>(13,0);
  191. double a14=P.at<double>(14,0);
  192. double cx=cameraMatrix.at<double>(0,2);
  193. double cy=cameraMatrix.at<double>(1,2);
  194. double fx=cameraMatrix.at<double>(0,0);
  195. double fy=cameraMatrix.at<double>(1,1);
  196. std::vector<cv::Point3d> pts3d;
  197. for(int i=0;i<points.size();++i)
  198. {
  199. double x=points[i].x/1000.0;
  200. double y=points[i].y/1000.0;
  201. double z=a0*pow(x,4)+a1*pow(y,4)+a2*x*x*x*y+a3*x*x*y*y+a4*x*y*y*y
  202. +a5*pow(x,3)+a6*pow(y,3)+a7*x*x*y+a8*x*y*y+a9*x*x+a10*y*y+a11*x*y
  203. +a12*x+a13*y+a14;
  204. //计算x,y
  205. double rx=(points[i].x-cx)/fx;
  206. pts3d.push_back(cv::Point3d(rx,0,z));
  207. }
  208. return pts3d;
  209. }