OpenCV双目立体视觉重建

devtools/2024/11/17 16:39:01/

         本篇文章主要给出使用opencv sgbm重建三维点云的代码,鉴于自身水平所限,如有错误,欢迎批评指正。

        环境:vs2015 ,opencv3.4.6,pcl1.8.0

        原始数据使用D455采集,图像已做完立体校正,如下图所示(欢迎进Q群交流:874653199):

        左图:

        右图:

         视差结果图:

        彩色视差结果图:

        点云结果:

3de4e29.png" width="1080" />

#include <iostream>
#include <fstream>#include <opencv2/opencv.hpp> 
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>#include<pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>#define isStereoRectify void visualize(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{pcl::visualization::PCLVisualizer viewer("3D Viewer");pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> src_h(cloud, 255, 255, 255);viewer.setBackgroundColor(0, 0, 0);viewer.addPointCloud(cloud, src_h, "cloud");while (!viewer.wasStopped()){viewer.spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}}void recon3d(cv::Mat disparty, double f, double cx, double cy, double baseline) {pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::PointXYZ singlePoint;for (int i = 0; i < disparty.rows; i++) {for (int j = 0; j < disparty.cols; j++) {const double disp = disparty.at<float>(i, j);if (disp == 0) {continue;}else {singlePoint.z = f*baseline / disp;singlePoint.x = (i - cx) / f *singlePoint.z;singlePoint.y = (j - cy) / f *singlePoint.z;if (singlePoint.z >= -0.65 && singlePoint.z <= 0.3) {cloud->points.emplace_back(singlePoint);}}}}visualize(cloud);pcl::io::savePLYFileBinary("cloud.ply", *cloud);}int main(){cv::Mat imageL = cv::imread("E:/2_光学测量/6_数据/6_stereo/l0.jpg",0);cv::Mat imageR = cv::imread("E:/2_光学测量/6_数据/6_stereo/r0.jpg", 0);cv::Mat cameraMatrixL = (cv::Mat_<double>(3, 3) << 428.406, 0.000000, 420.335, 0.000000, 428.406, 238.037, 0.000000, 0.000000, 1.000000);cv::Mat distCoeffL = (cv::Mat_<double>(5, 1) << 0, 0, 0, 0, 0);cv::Mat cameraMatrixR = (cv::Mat_<double>(3, 3) << 428.406, 0.000000, 420.335, 0.000000, 428.406, 238.037, 0.000000, 0.000000, 1.000000);cv::Mat distCoeffR = (cv::Mat_<double>(5, 1) << 0, 0, 0, 0, 0);cv::Mat R = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);cv::Mat T = (cv::Mat_<double>(3, 1) << -0.0949472, 0, 0);#ifdef isStereoRectifycv::Mat Rl, Rr, Pl, Pr, Q;cv::Rect validROIL, validROIR;cv::Size imageSize = imageL.size();cv::stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q, cv::CALIB_ZERO_DISPARITY,0, imageSize, &validROIL, &validROIR);cv::Mat mapLx, mapLy, mapRx, mapRy;cv::initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pl, imageSize, CV_32FC1, mapLx, mapLy);cv::initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);cv::Mat rectifyImageL, rectifyImageR;cv::remap(imageL, rectifyImageL, mapLx, mapLy, cv::INTER_LINEAR);cv::remap(imageR, rectifyImageR, mapRx, mapRy, cv::INTER_LINEAR);imageL = rectifyImageL;imageR = rectifyImageR;#endif // sterocv::namedWindow("disparity", CV_WINDOW_NORMAL);int SADWindowSize =5, numberOfDisparities = 128;cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, numberOfDisparities, SADWindowSize);sgbm->setPreFilterCap(64);sgbm->setBlockSize(SADWindowSize);sgbm->setP1(8 * SADWindowSize* SADWindowSize);sgbm->setP2(64 * SADWindowSize* SADWindowSize);sgbm->setMinDisparity(0);sgbm->setNumDisparities(numberOfDisparities);sgbm->setUniquenessRatio(10);sgbm->setSpeckleWindowSize(200);sgbm->setSpeckleRange(64);sgbm->setDisp12MaxDiff(1);sgbm->setMode(cv::StereoSGBM::MODE_SGBM);cv::Mat disp, disp8, dispf;sgbm->compute(imageL, imageR, disp);disp.convertTo(disp, CV_32F, 1.0 / 16.0);//1.0/16.0 disp.convertTo(disp8, CV_8U, 1.0);imshow("disparity", disp8);cv::imwrite("disp_mono.png", disp8);cv::Mat disp8_color;cv::applyColorMap(disp8, disp8_color, cv::COLORMAP_JET);imshow("disparity_color", disp8_color);cv::imwrite("disp_color.png", disp8_color);recon3d(disp, cameraMatrixL.at<double>(0,0), cameraMatrixL.at<double>(0, 2), cameraMatrixL.at<double>(1, 2), T.at<double>(0));cv::waitKey(0);return 0;}


http://www.ppmy.cn/devtools/134738.html

相关文章

驾校增加无人机培训项目可行性技术分析

驾校增加无人机培训项目的可行性技术分析&#xff0c;需要从市场需求、技术基础、政策支持、培训体系构建及运营等多个维度进行综合考量。以下是对这些方面的详细分析&#xff1a; 一、市场需求分析 1. 行业应用广泛&#xff1a;无人机在航拍、农业、环境监测、地理测绘、电力…

Gin 框架中的路由

1、路由概述 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等) 组成的,涉及到应用如何响应客户端对某个网站节点的访问。 RESTful API 是目前比较成熟的一套互联网应用程序的 API 设计理论,所以我们设计我们的路 由的时候建议参考 …

YOLOv7-0.1部分代码阅读笔记-general.py

general.py utils\general.py 目录 general.py 1.所需的库和模块 2.def set_logging(rank-1): 3.def init_seeds(seed0): 4.def get_latest_run(search_dir.): 5.def isdocker(): 6.def emojis(str): 7.def check_online(): 8.def check_git_status(): 9.de…

【系统架构设计师】真题论文: 论软件的静态演化和动态演化及其应用(包括解题思路和素材)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2010年 试题1)解题思路论文素材参考软件演化的重要性软件静态演化软件动态演化静态演化和动态演化的区别与联系软件静态演化和动态演化的应用案例(1)静态演化案例:企业办公自动化软件升级(2)动态演…

ERROR TypeError: AutoImport is not a function

TypeError: AutoImport is not a function 原因&#xff1a;unplugin-auto-import 插件版本问题 Vue3基于Webpack&#xff0c;在vue.config.js中配置 当unplugin-vue-components版本小于0.26.0时&#xff0c;使用以下写法 const { defineConfig } require("vue/cli-se…

数据湖与数据仓库的区别

数据湖与数据仓库是两种不同的数据存储和管理方式&#xff0c;它们在多个方面存在显著的区别。以下是对数据湖与数据仓库区别的详细阐述&#xff1a; 一、数据存储方式 数据仓库 通常采用预定义的模式和结构来存储数据。数据在存储前通常经过清洗、转换和整合等处理&#xff0…

HTML5 Video(视频)

HTML5 Video(视频) HTML5视频是现代网页设计中不可或缺的一部分,它允许开发者在网页中嵌入视频内容,为用户提供丰富多样的媒体体验。本文将深入探讨HTML5视频的各个方面,包括其基本用法、支持的格式、自定义播放器、浏览器兼容性以及最佳实践。 一、HTML5视频的基本用法 …

算法训练(leetcode)二刷第二十八天 | 509. 斐波那契数、70. 爬楼梯、*746. 使用最小花费爬楼梯

刷题记录 509. 斐波那契数70. 爬楼梯*746. 使用最小花费爬楼梯动态规划优化空间复杂度 509. 斐波那契数 leetcode题目地址 时间复杂度&#xff1a; O ( n ) O(n) O(n) 空间复杂度&#xff1a; O ( 1 ) O(1) O(1) // java class Solution {public int fib(int n) {if(n<…