线结构光中心点提取算法(原理,代码,优化)
1. 算法概述灰度重法线结构光重心点提取算法是一种用于结构光三维测量中对光条中心即重心点进行高精度、亚像素级定位的算法。2. 数学模型灰度重心横坐标计算公式取图像第行各列坐标处灰度C代码实现#include opencv2/opencv.hpp #include vector #include iostream #include algorithm using namespace cv; using namespace std; /** * 运行环境 C17 opencv 4.0 * brief 灰度重心法逐行提取激光条纹中心点 * param grayImg 输入单通道灰度图像 * param thresh 灰度阈值大于阈值才判定为激光有效像素 * param centerPoints 输出所有有效激光中心点 (x亚像素, y行号) * return 返回提取到的中心点总个数 */ int getLaserCenterByGrayCentroid(const Mat grayImg, int thresh, vectorPoint2f centerPoints) { centerPoints.clear(); int rows grayImg.rows; // 图像总行数(y方向) int cols grayImg.cols; // 图像总列数(x方向) // 逐行遍历图像每一行 y i for (int i 0; i rows; i) { double sum_xI 0.0; // 分子Σ x * I(x,i) double sum_I 0.0; // 分母Σ I(x,i) // 遍历当前行所有列像素 for (int x 0; x cols; x) { uchar grayVal grayImg.atuchar(i, x); // 灰度大于阈值属于激光区域参与重心计算 if (grayVal thresh) { sum_xI x * grayVal; sum_I grayVal; } } // 分母趋近于0该行无激光条纹跳过不计入总数 if (sum_I 1e-6) continue; // 灰度重心计算公式gi ΣxI / ΣI double g_i sum_xI / sum_I; centerPoints.emplace_back((float)g_i, (float)i); } // 返回中心点总数量 return centerPoints.size(); } int main() { // 1. 读取激光条纹图像 Mat src imread(camera_8.bmp); // 替换为你的图片路径 if (src.empty()) { cout 图片读取失败请检查文件路径 endl; return -1; } Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); // 转为单通道灰度图 // 2. 参数配置 int grayThresh 30; // 背景过滤阈值根据图像亮度自行调整 vectorPoint2f laserCenters; // 存储全部激光中心点 // 3. 提取中心线并获取中心点总数 int totalPointNum getLaserCenterByGrayCentroid(gray, grayThresh, laserCenters); // 4. 控制台输出总点数 部分坐标信息 cout endl; cout 整张图像激光中心点总数 totalPointNum endl; cout endl; // 可选打印前15个中心点坐标 cout 前15组中心坐标 (x亚像素, y行号) endl; int printCnt min(15, totalPointNum); for (int k 0; k printCnt; k) { printf(第%3d点: x%.3f , y%.0f\n, k 1, laserCenters[k].x, laserCenters[k].y); } // 5. 在原图绘制红色中心点可视化结果 Mat drawImg src.clone(); for (const auto pt : laserCenters) { circle(drawImg, pt, 1, Scalar(0, 0, 255), -1); } // 窗口展示 imshow(原图, src); imshow(灰度图像, gray); imshow(激光中心线提取结果, drawImg); waitKey(0); destroyAllWindows(); return 0; }原图线激光中心提取后3.算法优化从提取效果可知算法提取的效果在无反光处提取质量较好但当在反光处时提取精度会降低。可从两个角度优化本文只提出两点3.1 ROI约束参考裴凯.高反光表面线结构光三维测量技术研究[D].吉林大学代码为数学模型可从代码中分析#include opencv2/opencv.hpp #include vector #include iostream #include algorithm using namespace cv; using namespace std; /** * brief 带相邻行窗口约束的灰度重心法提取激光条纹中心 * 规则首行整行遍历后续每行仅在上一行中心xg±d范围内计算重心 * param grayImg 输入单通道灰度图 * param thresh 激光灰度阈值 * param searchWinD 左右搜索半宽d下一行检索区间 [xg-d, xgd] * param centerPoints 输出亚像素中心点序列 * return 有效中心点总数 */ int getLaserCenterByGrayCentroidTrack(const Mat grayImg, int thresh, int searchWinD, vectorPoint2f centerPoints) { centerPoints.clear(); int rows grayImg.rows; int cols grayImg.cols; // 记录上一行计算得到的中心x坐标初始标记为无效 double prevXg -1.0; for (int y 0; y rows; y) { double sum_xI 0.0; double sum_I 0.0; // 确定当前行需要遍历的x起止范围 int xStart, xEnd; if (prevXg 0) { // 没有上一行参考点首行/连续无激光行整行遍历 xStart 0; xEnd cols - 1; } else { // 以上一行中心为基准限定左右d像素窗口 xStart static_castint(round(prevXg)) - searchWinD; xEnd static_castint(round(prevXg)) searchWinD; // 边界钳位防止越界 xStart max(0, xStart); xEnd min(cols - 1, xEnd); } // 仅遍历限定区间内的列像素 for (int x xStart; x xEnd; x) { uchar grayVal grayImg.atuchar(y, x); if (grayVal thresh) { sum_xI x * grayVal; sum_I grayVal; } } // 当前行无有效激光像素跳过保留上一行标记不变 if (sum_I 1e-6) { continue; } // 计算本行亚像素中心 double currXg sum_xI / sum_I; centerPoints.emplace_back(static_castfloat(currXg), static_castfloat(y)); // 更新上一行x坐标给下一行做检索基准 prevXg currXg; } return centerPoints.size(); } int main() { // 1. 读取图像 Mat src imread(camera_8.bmp); if (src.empty()) { cout 图片读取失败请检查文件路径 endl; return -1; } Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); // 2. 可调参数 int grayThresh 30; // 背景灰度阈值 int d 25; // 相邻行左右搜索半宽度d可根据条纹粗细调整 vectorPoint2f laserCenters; // 3. 跟踪式重心提取 int totalPointNum getLaserCenterByGrayCentroidTrack(gray, grayThresh, d, laserCenters); // 4. 控制台信息输出 cout endl; cout 搜索窗口半宽 d d endl; cout 整张图像激光中心点总数 totalPointNum endl; cout endl; cout 前15组中心坐标 (x亚像素, y行号) endl; int printCnt min(15, totalPointNum); for (int k 0; k printCnt; k) { printf(第%3d点: x%.3f , y%.0f\n, k 1, laserCenters[k].x, laserCenters[k].y); } // 5. 绘制中心点可视化 Mat drawImg src.clone(); for (const auto pt : laserCenters) { circle(drawImg, pt, 1, Scalar(0, 0, 255), -1); } imshow(原图, src); imshow(灰度图像, gray); imshow(带行跟踪约束激光中心线, drawImg); waitKey(0); destroyAllWindows(); return 0; }3.2 能量法优化模型从代码分析能量法周渊,孟祥群,江登表,等.复杂干扰情况下的结构光条纹中心提取方法[J].中国激光,2020,47(12):172-180#include opencv2/opencv.hpp #include vector #include iostream #include algorithm #include cmath #include limits using namespace cv; using namespace std; /** * brief 基于距离-灰度代价函数约束窗口的灰度重心激光提取 * 代价公式 f d * exp(-H / k)寻找f最小位置作为下一行检索中心 * param grayImg 输入单通道灰度图 * param thresh 激光灰度阈值 * param k 指数常数(k1)控制灰度权重 * param winHalf 检索窗口半宽[A-best-winHalf, A-bestwinHalf] * param centerPoints 输出亚像素中心点序列 * return 有效中心点总数 */ int getLaserCenterCostTrack( const Mat grayImg, int thresh, double k, int winHalf, vectorPoint2f centerPoints ) { centerPoints.clear(); int rows grayImg.rows; int cols grayImg.cols; // 保存上一行有效中心x坐标初始无效标记 double prevX -1.0; for (int y 0; y rows; y) { double sum_xI 0.0; double sum_I 0.0; int xStart, xEnd; if (prevX 0) { // 首行/连续无激光行整行遍历 xStart 0; xEnd cols - 1; } else { // 1. 遍历本行所有x计算代价f寻找最小f对应的A点 double minF numeric_limitsdouble::max(); int bestA_x static_castint(round(prevX)); for (int x 0; x cols; x) { // 两点欧式距离d(x,y) 与 (prevX, y-1) double d sqrt(pow(x - prevX, 2) pow(y - (y - 1), 2)); uchar H grayImg.atuchar(y, x); // 代价函数 f d * exp(-H / k) double f 1-exp(-H/k) d; // 更新最小代价对应横坐标 // if(d) if (f minF) { minF f; bestA_x x; } } // 2. 以bestA_x为中心划定左右检索窗口 xStart bestA_x - winHalf; xEnd bestA_x winHalf; // 边界保护防止越界 xStart max(0, xStart); xEnd min(cols - 1, xEnd); } // 3. 窗口内灰度重心计算 for (int x xStart; x xEnd; x) { uchar grayVal grayImg.atuchar(y, x); if (grayVal thresh) { sum_xI (double)x * grayVal; sum_I grayVal; } } // 无有效激光像素跳过本行prevX保持不变 if (sum_I 1e-6) { continue; } // 计算亚像素中心 double currX sum_xI / sum_I; centerPoints.emplace_back((float)currX, (float)y); // 更新上一行中心供给下一行代价计算 prevX currX; } return centerPoints.size(); } int main() { // 1. 读取图像 Mat src imread(camera_8.bmp); if (src.empty()) { cout 图片读取失败请检查文件路径 endl; return -1; } Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); // 可调参数区 int grayThresh 30; // 灰度阈值 double k 8.0; // 指数常数 k1越大灰度影响越弱 int winHalf 20; // 最终重心计算窗口半宽 d // vectorPoint2f laserCenters; int totalPointNum getLaserCenterCostTrack(gray, grayThresh, k, winHalf, laserCenters); // 控制台信息输出 cout endl; cout 指数系数 k k endl; cout 重心窗口半宽 winHalf endl; cout 激光中心点总数 totalPointNum endl; cout endl; // 打印前15组坐标 cout 前15组中心坐标 (x亚像素, y行号) endl; int printCnt min(15, totalPointNum); for (int kk 0; kk printCnt; kk) { printf(第%3d点: x%.3f , y%.0f\n, kk 1, laserCenters[kk].x, laserCenters[kk].y); } // 绘制中心点可视化 Mat drawImg src.clone(); for (const auto pt : laserCenters) { circle(drawImg, pt, 1, Scalar(0, 0, 255), -1); } imshow(原图, src); imshow(灰度图像, gray); imshow(代价函数约束激光中心线, drawImg); waitKey(0); destroyAllWindows(); return 0; }优化后总结这些算法不仅仅适用于“直线型”场景下的光条还可适用于更复杂的场景但是鲁棒性待优化。

相关新闻

如何快速解放双手:20+项原神自动化工具的完整指南

如何快速解放双手:20+项原神自动化工具的完整指南

如何快速解放双手:20项原神自动化工具的完整指南 【免费下载链接】better-genshin-impact 📦BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连音游 | 自动烹…

2026/8/2 8:27:28阅读更多 →
学术严密性与 AI 检出率冲突怎么破?论文去 AI 痕迹的逻辑重构实操(无广纯享)

学术严密性与 AI 检出率冲突怎么破?论文去 AI 痕迹的逻辑重构实操(无广纯享)

每个在毕业季修改论文的同学,大概率都会面临一个无法避开的学术死循环:为了满足学术论文的严谨度,我们需要使用极具逻辑性、结构严密的句式和学术大词;但这种极其规整、平滑的学术句法,在 AIGC 检测系统的眼里&#xf…

2026/8/2 8:27:28阅读更多 →
2026企业文件管理系统横向对比测评|通用选型标准与场景适配指南

2026企业文件管理系统横向对比测评|通用选型标准与场景适配指南

随着企业数字化建设不断推进,企业产生的文档、素材、项目资料、业务数据体量持续增长。传统依靠本地文件夹、即时通讯传输、人工归档的文件管理方式,普遍存在文件分散、版本混乱、检索低效、协作困难、数据无沉淀、权限无管控等问题,难以适配…

2026/8/2 8:25:28阅读更多 →
Mac微信防撤回终极解决方案:3分钟实现消息永久保留

Mac微信防撤回终极解决方案:3分钟实现消息永久保留

Mac微信防撤回终极解决方案:3分钟实现消息永久保留 【免费下载链接】WeChatIntercept 微信防撤回插件,一键安装,MAC可用,支持最新v4.1.10微信 项目地址: https://gitcode.com/gh_mirrors/we/WeChatIntercept 还在为错过重要…

2026/8/2 9:41:45阅读更多 →
Unity触发器失效?5个配置雷区与解决方案详解

Unity触发器失效?5个配置雷区与解决方案详解

1. 项目概述:为什么你的触发器总是不工作? 在Unity里做交互,触发器(Trigger)绝对是高频使用的功能。无论是角色进入一个区域触发剧情,还是拾取一个道具,都离不开它。但很多开发者,尤…

2026/8/2 9:41:45阅读更多 →
终极ThinkPad风扇控制指南:如何通过TPFanCtrl2实现完美散热与静音平衡

终极ThinkPad风扇控制指南:如何通过TPFanCtrl2实现完美散热与静音平衡

终极ThinkPad风扇控制指南:如何通过TPFanCtrl2实现完美散热与静音平衡 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 作为一名ThinkPad用户,你…

2026/8/2 9:41:45阅读更多 →
解锁AMD Ryzen性能潜能:3步掌握SMUDebugTool硬件级调优

解锁AMD Ryzen性能潜能:3步掌握SMUDebugTool硬件级调优

解锁AMD Ryzen性能潜能:3步掌握SMUDebugTool硬件级调优 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://g…

2026/8/2 9:41:45阅读更多 →
WarcraftHelper魔兽争霸助手:让经典游戏在现代电脑上焕发新生的终极解决方案

WarcraftHelper魔兽争霸助手:让经典游戏在现代电脑上焕发新生的终极解决方案

WarcraftHelper魔兽争霸助手:让经典游戏在现代电脑上焕发新生的终极解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为怀旧的…

2026/8/2 9:41:45阅读更多 →
从写代码到给指令:Claude Code如何把产品构建效率拉升一个维度

从写代码到给指令:Claude Code如何把产品构建效率拉升一个维度

从写代码到给指令:Claude Code如何把产品构建效率拉升一个维度 它不是帮你补全代码,而是替你完成整个开发循环。 一、一个让你似曾相识的深夜 凌晨两点,你盯着屏幕上一份别人留下的祖传代码,要在里面加一个新功能。 调用链路横跨…

2026/8/2 9:39:45阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字媒体创作领域,视频编辑处理的质量损…

2026/8/2 1:29:34阅读更多 →
AI辅助本科论文写作:8大工具评测与高效使用指南

AI辅助本科论文写作:8大工具评测与高效使用指南

1. 本科生论文写作的AI辅助现状本科毕业论文是每个大学生必须跨越的一道坎。记得我当年写论文时,光是文献检索就花了整整两周时间,打印的参考文献堆满了半个书桌。如今AI技术的发展为学术写作带来了革命性变化,合理使用这些工具可以节省80%以…

2026/8/2 2:32:55阅读更多 →
如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票…

2026/8/2 2:09:20阅读更多 →