欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

【OpenCV3】基于双目视觉的三维重建

发布时间:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【OpenCV3】基于双目视觉的三维重建 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

opencv中双目视觉立体重建根据的是三角形原理,在经过摄像机立体标定之后获取到单个摄像机的参数和双目系统的立体参数,根据三角形原理,我们即可实现对点云的三维重建,这里我们只介绍对单个点的三维重建。


具体见如下代码:

#include <string> #include <opencv2\opencv.hpp>//从.yml文件中读取摄像机参数 bool load_calibration_yml(std::string& file_name, cv::Mat& cam_k_left, cv::Mat& cam_k_right,cv::Mat& cam_kc_left, cv::Mat& cam_kc_right, cv::Mat& R, cv::Mat& T) {cv::FileStorage fs(file_name, cv::FileStorage::READ);if (!fs.isOpened()){return false;}fs["cam_K_left"] >> cam_k_left;if (3 != cam_k_left.rows || 3 != cam_k_left.cols){std::cout << "Load cam_K_left failed" << std::endl;return false;}fs["cam_kc_left"] >> cam_kc_left;if (1 != cam_kc_left.rows || 5 != cam_kc_left.cols){std::cout << "Load cam_kc_left failed" << std::endl;return false;}fs["cam_K_right"] >> cam_k_right;if (3 != cam_k_right.rows || 3 != cam_k_right.cols){std::cout << "Load cam_K_right failed" << std::endl;return false;}fs["cam_kc_right"] >> cam_kc_right;if (1 != cam_kc_left.rows || 5 != cam_kc_left.cols){std::cout << "Load cam_kc_right failed" << std::endl;return false;}fs["R"] >> R;if (3 != R.rows || 3 != R.cols){std::cout << "Load R failed" << std::endl;return false;}fs["T"] >> T;if (3 != T.rows || 1 != T.cols){std::cout << "Load T failed" << std::endl;return false;}return false;}//对单个点进行畸变校正 void undist_point(cv::Point2d& input, cv::Point2d& output, cv::Mat& K, cv::Mat& kc) {double x = (input.x - K.at<double>(0, 2)) / K.at<double>(0, 0);double y = (input.y - K.at<double>(1, 2)) / K.at<double>(1, 1);double r = std::sqrt(std::pow(x, 2) + std::pow(y, 2));double theta = std::atan(r / FOCAL_LENTH);double theta_3 = std::pow(theta, 3);double theta_5 = std::pow(theta, 5);double theta_7 = std::pow(theta, 7);double theta_9 = std::pow(theta, 9);double theta_f = theta * kc.at<double>(0, 0) + theta_3 * kc.at<double>(0, 1) + theta_5 * kc.at<double>(0, 2) + theta_7 * kc.at<double>(0, 3) + theta_9 * kc.at<double>(0, 4);//std::cout << "theta_f= " << theta_f << std::endl;double phi = std::atan(std::abs(y) / std::abs(x));output.x = x / std::abs(x) * std::cos(phi) * theta_f * K.at<double>(0, 0) + K.at<double>(0, 2);output.y = y / std::abs(y) * std::sin(phi) * theta_f * K.at<double>(1, 1) + K.at<double>(1, 2);return; }//对单个点进行三角化立体重建 void triangulate_stereo(cv::Mat & K1, cv::Mat & kc1, cv::Mat & K2, cv::Mat & kc2, cv::Mat & Rt,cv::Mat & T, cv::Point2d & p1, cv::Point2d & p2, cv::Point3d & p3d) {cv::Point2d outp1, outp2;undist_point(p1, outp1, K1, kc1);undist_point(p2, outp2, K2, kc2);//std::cout << "undist_left = " << outp1 << std::endl;//std::cout << "undist_right = " << outp2 << std::endl;double f1 = std::sqrt(std::pow(K1.at<double>(0, 0), 2) + std::pow(K1.at<double>(1, 1), 2)) * FOCAL_LENTH;double f2 = std::sqrt(std::pow(K2.at<double>(0, 0), 2) + std::pow(K2.at<double>(1, 1), 2)) * FOCAL_LENTH;cv::Point3d u1(outp1.x, outp1.y, f1);cv::Point3d u2(outp2.x, outp2.y, f2);cv::Point3d w1 = u1;cv::Point3d w2 = cv::Point3d(cv::Mat(Rt*(cv::Mat(u2))));//std::cout << "w1 = " << w1 << std::endl;//std::cout << "w2 = " << w2 << std::endl;double disparity = w1.x - w2.x;double X = w1.x - K1.at<double>(0, 2);double Y = w1.y - K1.at<double>(1, 2);double Z = f1;double W = disparity * (-1/T.at<double>(0, 0)) + (K1.at<double>(0, 2) - K2.at<double>(0, 2))/T.at<double>(0, 0);p3d.x = X / W;p3d.y = Y / W;p3d.z = Z / W;return; }

2017.05.11

总结

以上是生活随笔为你收集整理的【OpenCV3】基于双目视觉的三维重建的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。