opencv--3d数据拟合平面并对倾斜平面矫正

2024-06-03 20:36

本文主要是介绍opencv--3d数据拟合平面并对倾斜平面矫正,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对于深度数据而言,mat记录的是深度值,当对深度值进行各种处理,例如获取直线、圆、椭圆等其他形状时,如果平面没有完全水平,你使用opencv处理精度是有损失的,因此这里使用opencv 先对平面进行矫正,矫正原理是在有效平面内随机采集3000点的深度数据,使用深度数据进行拟合平面,计算平面的倾斜较大,然后使用角度对原始数据进行矫正,代码如下:

// 将深度图转换为点云
std::vector<cv::Point3f> depthToPointCloud(const cv::Mat& depthImage) {std::vector<cv::Point3f> pointCloud;// 设置随机数生成器std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> distRow(0, depthImage.rows - 1);std::uniform_int_distribution<> distCol(0, depthImage.cols - 1);// 要提取的像素点数量int numPixels = 2000; // 你可以根据需要调整这个数量// 存储随机提取的像素点std::vector<cv::Vec3b> randomPixels;for (int i = 0; i < numPixels; ++i) {int y = distRow(gen);int x = distCol(gen);//randomPixels.push_back(image.at<cv::Vec3b>(row, col));cv::Point3f point((float)x, (float)y, depthImage.at<float>(y, x)); // 构造三维点pointCloud.push_back(point); // 添加到点云}//for (int y = 0; y < depthImage.rows; ++y) {//    for (int x = 0; x < depthImage.cols; ++x) {//        float depth = depthImage.at<float>(y, x); // 获取深度值//        //if (std::isnan(depth) || depth <= 0.0) {//        //    continue; // 跳过无效深度值//        //}//        cv::Point3f point((float)x, (float)y, depth); // 构造三维点//        pointCloud.push_back(point); // 添加到点云//    }//}return pointCloud;
}// 函数:拟合平面
cv::Vec4f fitPlaneRANSAC(const std::vector<cv::Point3f>& points, int maxIter = 1000, float threshold = 0.01) {if (points.empty())return cv::Vec4f();cv::Vec4f bestPlane;int bestInliers = 0;for (int iter = 0; iter < maxIter; ++iter) {// 随机选择三个点std::vector<int> indices(points.size());std::iota(indices.begin(), indices.end(), 0);std::shuffle(indices.begin(), indices.end(), std::default_random_engine(5));cv::Point3f p1 = points[indices[0]];cv::Point3f p2 = points[indices[1]];cv::Point3f p3 = points[indices[2]];// 计算平面的法向量cv::Point3f v1 = p2 - p1;cv::Point3f v2 = p3 - p1;cv::Point3f normal = v1.cross(v2);normal /= cv::norm(normal);// 平面公式:Ax + By + Cz + D = 0float D = -normal.dot(p1);cv::Vec4f plane(normal.x, normal.y, normal.z, D);// 计算内点数量int inliers = 0;for (const auto& point : points) {float distance = std::abs(plane[0] * point.x + plane[1] * point.y + plane[2] * point.z + plane[3]);if (distance < threshold) {inliers++;}}// 更新最佳平面if (inliers > bestInliers) {bestInliers = inliers;bestPlane = plane;}}return bestPlane;
}// 函数:矫正平面
void correctPlane(const cv::Vec4f& plane, cv::Mat& points) {cv::Mat normal_m, normal_m_8;cv::normalize(points, normal_m, 1, 0, cv::NORM_MINMAX);normal_m.convertTo(normal_m_8, CV_8U, 255.0);cv::Vec3f normal(plane[0], plane[1], plane[2]);cv::Vec3f zAxis(0, 0, 1);cv::Vec3f rotationAxis = normal.cross(zAxis);float angle = std::acos(normal.dot(zAxis) / (cv::norm(normal) * cv::norm(zAxis)));cv::Mat rotationMatrix;cv::Rodrigues(rotationAxis * angle, rotationMatrix);for (int i = 0; i < points.rows; ++i) {cv::Vec3f point = points.at<cv::Vec3f>(i);// 将 point 转换为 cv::Mat 类型cv::Mat pointMat = (cv::Mat_<float>(3, 1) << point[0], point[1], point[2]);// 矩阵乘法cv::Mat transformedPointMat = rotationMatrix * pointMat;// 将结果转换回 cv::Vec3f 类型points.at<cv::Vec3f>(i) = cv::Vec3f(transformedPointMat.at<float>(0), transformedPointMat.at<float>(1), transformedPointMat.at<float>(2));}cv::Mat normal_m_, normal_m_8_;cv::normalize(points, normal_m_, 1, 0, cv::NORM_MINMAX);normal_m_.convertTo(normal_m_8_, CV_8U, 255.0);}

从矫正前的数据和矫正后的数据可以发现,平面得到了很好得了很好的矫正。

这篇关于opencv--3d数据拟合平面并对倾斜平面矫正的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028046

相关文章

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

Oracle存储过程里操作BLOB的字节数据的办法

《Oracle存储过程里操作BLOB的字节数据的办法》该篇文章介绍了如何在Oracle存储过程中操作BLOB的字节数据,作者研究了如何获取BLOB的字节长度、如何使用DBMS_LOB包进行BLOB操作... 目录一、缘由二、办法2.1 基本操作2.2 DBMS_LOB包2.3 字节级操作与RAW数据类型2.