优秀的zhang-suen细化+灰度重心法

先用zhang-suen细化对激光光条做细化,然后在使用灰度重心法可以达到亚像素提取,精度还是可以的,但是对我的数据集不是很友好,代码是看其他博主的,代码可以参考代码连接----------论文连接

上代码

#include<opencv2/core/core.hpp>
#include<opencv2/calib3d/calib3d.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<fstream>
#include<stdlib.h>using namespace std;
using namespace cv;//-------------------------------------------zhang细化算法----------------------------------------------//
void zhang(Mat& input, Mat& output)
{Mat copymat;input.copyTo(copymat);int k = 0;//防止溢出while (1){k++;bool stop = false;//step1for (int i = 1; i < input.cols - 1; i++)for (int j = 1; j < input.rows - 1; j++){if (input.at<uchar>(j, i) > 0){int p1 = int(input.at<uchar>(j, i)) > 0 ? 1 : 0;int p2 = int(input.at<uchar>(j - 1, i)) > 0 ? 1 : 0;int p3 = int(input.at<uchar>(j - 1, i + 1)) > 0 ? 1 : 0;int p4 = int(input.at<uchar>(j, i + 1)) > 0 ? 1 : 0;int p5 = int(input.at<uchar>(j + 1, i + 1)) > 0 ? 1 : 0;int p6 = int(input.at<uchar>(j + 1, i)) > 0 ? 1 : 0;int p7 = int(input.at<uchar>(j + 1, i - 1)) > 0 ? 1 : 0;int p8 = int(input.at<uchar>(j, i - 1)) > 0 ? 1 : 0;int p9 = int(input.at<uchar>(j - 1, i - 1)) > 0 ? 1 : 0;int np1 = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;int sp2 = (p2 == 0 && p3 == 1) ? 1 : 0;int sp3 = (p3 == 0 && p4 == 1) ? 1 : 0;int sp4 = (p4 == 0 && p5 == 1) ? 1 : 0;int sp5 = (p5 == 0 && p6 == 1) ? 1 : 0;int sp6 = (p6 == 0 && p7 == 1) ? 1 : 0;int sp7 = (p7 == 0 && p8 == 1) ? 1 : 0;int sp8 = (p8 == 0 && p9 == 1) ? 1 : 0;int sp9 = (p9 == 0 && p2 == 1) ? 1 : 0;int sp1 = sp2 + sp3 + sp4 + sp5 + sp6 + sp7 + sp8 + sp9;if (np1 >= 2 && np1 <= 6 && sp1 == 1 && ((p2 * p4 * p6) == 0) && ((p4 * p6 * p8) == 0)){stop = true;copymat.at<uchar>(j, i) = 0;}}}//step2for (int i = 1; i < input.cols - 1; i++){for (int j = 1; j < input.rows - 1; j++){if (input.at<uchar>(j, i) > 0){int p2 = int(input.at<uchar>(j - 1, i)) > 0 ? 1 : 0;int p3 = int(input.at<uchar>(j - 1, i + 1)) > 0 ? 1 : 0;int p4 = int(input.at<uchar>(j, i + 1)) > 0 ? 1 : 0;int p5 = int(input.at<uchar>(j + 1, i + 1)) > 0 ? 1 : 0;int p6 = int(input.at<uchar>(j + 1, i)) > 0 ? 1 : 0;int p7 = int(input.at<uchar>(j + 1, i - 1)) > 0 ? 1 : 0;int p8 = int(input.at<uchar>(j, i - 1)) > 0 ? 1 : 0;int p9 = int(input.at<uchar>(j - 1, i - 1)) > 0 ? 1 : 0;int np1 = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;int sp2 = (p2 == 0 && p3 == 1) ? 1 : 0;int sp3 = (p3 == 0 && p4 == 1) ? 1 : 0;int sp4 = (p4 == 0 && p5 == 1) ? 1 : 0;int sp5 = (p5 == 0 && p6 == 1) ? 1 : 0;int sp6 = (p6 == 0 && p7 == 1) ? 1 : 0;int sp7 = (p7 == 0 && p8 == 1) ? 1 : 0;int sp8 = (p8 == 0 && p9 == 1) ? 1 : 0;int sp9 = (p9 == 0 && p2 == 1) ? 1 : 0;int sp1 = sp2 + sp3 + sp4 + sp5 + sp6 + sp7 + sp8 + sp9;if (np1 >= 2 && np1 <= 6 && sp1 == 1 && (p2 * p4 * p8) == 0 && (p2 * p6 * p8) == 0){stop = true;copymat.at<uchar>(j, i) = 0;}}}}//将新得到的图片赋给新的图片copymat.copyTo(input);if (!stop){break;}}copymat.copyTo(output);
}//第i,j个点像素值double ijpixel(double& x, double& y, Mat& m)
{int x_0 = int(x);int x_1 = int(x + 1);int y_0 = int(y);int y_1 = int(y + 1);int px_0y_0 = int(m.at<uchar>(y_0, x_0));int px_0y_1 = int(m.at<uchar>(y_1, x_0));int px_1y_0 = int(m.at<uchar>(y_0, x_1));int px_1y_1 = int(m.at<uchar>(y_1, x_1));double x_y0 = px_0y_0 + (x - double(x_0)) * (px_1y_0 - px_0y_0);double x_y1 = px_0y_1 + (x - double(x_0)) * (px_1y_1 - px_0y_1);double x_y = x_y0 + (y - double(y_0)) * (x_y1 - x_y0);return x_y;
}//normal vector
void CalcNormVec(Point2d ptA, Point2d ptB, Point2d ptC, double pfCosSita, double pfSinSita)
{double fVec1_x, fVec1_y, fVec2_x, fVec2_y;if (ptA.x == 0 && ptA.y == 0){ptA.x = ptC.x;ptA.y = ptC.y;//先用B点坐标减A点坐标。fVec1_x = -(ptB.x - ptA.x);fVec1_y = -(ptB.y - ptA.y);}else{//先用B点坐标减A点坐标。fVec1_x = ptB.x - ptA.x;fVec1_y = ptB.y - ptA.y;}if (ptC.x == 0 && ptC.y == 0){ptC.x = ptA.x;ptC.y = ptA.y;//再用C点坐标减B点坐标。fVec2_x = (ptB.x - ptC.x);fVec2_y = (ptB.y - ptC.y);}else{//再用C点坐标减B点坐标。fVec2_x = ptC.x - ptB.x;fVec2_y = ptC.y - ptB.y;}//单位化。double fMod = sqrt(fVec1_x * fVec1_x + fVec1_y * fVec1_y);fVec1_x /= fMod;fVec1_y /= fMod;//计算垂线。double fPerpendicularVec1_x = -fVec1_y;double fPerpendicularVec1_y = fVec1_x;//单位化。fMod = sqrt(fVec2_x * fVec2_x + fVec2_y * fVec2_y);fVec2_x /= fMod;fVec2_y /= fMod;//计算垂线。double fPerpendicularVec2_x = -fVec2_y;double fPerpendicularVec2_y = fVec2_x;//求和。double fSumX = fPerpendicularVec1_x + fPerpendicularVec2_x;double fSumY = fPerpendicularVec1_y + fPerpendicularVec2_y;//单位化。fMod = sqrt(fSumX * fSumX + fSumY * fSumY);double fCosSita = fSumX / fMod;double fSinSita = fSumY / fMod;pfCosSita = fCosSita;pfSinSita = fSinSita;
}void point(Mat& inputimg, vector<Point2d>& pt)
{pt.push_back(Point2d(0, 0));for (int i = 0; i < inputimg.cols; i++)for (int j = 0; j < inputimg.rows; j++){if (inputimg.at<uchar>(j, i) >= 95){Point2d curr = Point2d(i, j);pt.push_back(curr);}}pt.push_back(Point2d(0, 0));
}int main()
{ofstream of1, of2;of1.open("x.txt", ios::trunc);of2.open("y.txt", ios::trunc);Mat img, img1, img2, ori;img = imread(".\\train\\images_name\\6.png");ori = img;cvtColor(img, img, COLOR_RGB2GRAY);GaussianBlur(img, img, Size(3, 3), 0);img.copyTo(img2); // 高斯模板处理后的图像threshold(img, img, 95, 255, 3); // 设置阈值zhang(img, img1);  // zhang-suen阈值处理后的图像vector<Point2d> points; point(img1, points);vector<double> kcal;for (int i = 1; i < points.size() - 1; i++){//normaldouble pfCosSita = 0, pfSinSita = 0;CalcNormVec(Point2d(points[i - 1].x, points[i - 1].y), Point2d(points[i].x, points[i].y), Point2d(points[i + 1].x, points[i + 1].y), pfCosSita, pfSinSita);//-------------------灰度中心法gdd---------------------//double sum = 0, sum_sumx = 0, sum_sumy = 0;for (int j = 0; j < 2; j++){if (j == 0){double cj = points[i].x;double ci = points[i].y;sum = ijpixel(cj, ci, img2);sum_sumx = ijpixel(cj, ci, img2) * cj;sum_sumy = ijpixel(cj, ci, img2) * ci;}else{double x_cor = points[i].x + j * pfCosSita;double y_cor = points[i].y + j * pfSinSita;double x_cor1 = points[i].x - j * pfCosSita;double y_cor1 = points[i].y - j * pfSinSita;sum = sum + ijpixel(x_cor, y_cor, img2) + ijpixel(x_cor1, y_cor1, img2);sum_sumx = sum_sumx + ijpixel(x_cor, y_cor, img2) * x_cor + ijpixel(x_cor1, y_cor1, img2) * x_cor1;sum_sumy = sum_sumy + ijpixel(x_cor, y_cor, img2) * y_cor + ijpixel(x_cor1, y_cor1, img2) * y_cor1;}}//图像中心线画出来circle(img1, Point(sum_sumx / sum, sum_sumy / sum), 1, Scalar(0, 0, 255));//circle(ori, Point(sum_sumx / sum, sum_sumy / sum), 1, Scalar(0, 0, 255));}//imshow("设置阈值处理", img);//imshow("高斯模板处理", img2);imshow("灰度重心法处理", img1);imwrite("zhang-suen1.png", img1);//imwrite("zhang-suen.png", img);waitKey(0);system("pause");return 0;
}

贴结果

我建立了一个激光条纹提取的群,欢迎小伙伴加入,学习交流:点击链接加入群聊【激光条纹中心提取】 先申明本人是学生,不涉及营销、宣传、推广、盈利,单纯为了学习交流,所以心怀不轨的请绕道!!!

激光条纹中心提取——zhang细化+灰度重心法相关推荐

  1. 激光条纹中心提取——灰度中心法python

    激光条纹中心提取--灰度中心法python 灰度中心法 python代码 灰度中心法 灰度重心法是根据每行光条纹横截面内的灰度分布特征逐行进行处理,通过在行坐标的方向上,逐行计算提取光条纹区域的灰度重 ...

  2. 传统激光条纹中心提取算法研究现状

    传统激光条纹中心提取算法研究现状 前言 一.边缘法 二.中心法 三.阈值法 四. 细化法 五.极值法 六.灰度重心法 七.方向模板 八.曲线拟合法 九.Steger 前言 光条中心提取是将宽度大于1的 ...

  3. 激光条纹中心提取——方法总结

    激光条纹中心提取--方法总结 算法 优势 缺点 边缘法 处理速度快:适用于精度要求低的大型物体测量 存在很大误差:要求图像质量较好且结构光特性较高 中心法 适用于条纹质量好且形状规则的物体测量:精度高 ...

  4. 激光条纹中心提取——Zhang-Suen法python

    Zhang-Suen法 原理-- Zhang-Suen法 代码--python代码 原理-- Zhang-Suen法 细化法(又称形态学骨架法)是通过对光条纹不断地进行腐蚀操作,剥离光条纹边界,得到单 ...

  5. 激光条纹中心提取——ZhangSuen法python

    ZhangSuen法: 论文连接:A fast parallel algorithm for thinning digital patterns 代码连接:https://github.com/bsd ...

  6. 【必备知识】:线激光条纹中心线提取算法导读

    线激光条纹特性 线激光器是由点激光器和前置透镜组成的.点激光器可以为He-Ne激光器或半导体激光器.相比较He-Ne激光器,半导体激光器因其输出光源具有发散性,更适合用于制作线激光器.需要说明的是,半 ...

  7. 中线提取算法_综述|线结构光中心提取算法研究发展

    摘 要: 线结构光扫描是三维重建领域的关键技术.光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素.本文详细阐述了光条纹中心提取算法的理论基础及发展历程,将现有算法分为三类 ...

  8. 灰度重心法提取光条纹中心

    灰度重心法提取激光光条纹中心其实是将光条纹截面的灰度值分布中的质心记作为光条纹的中心. 在一列线激光中先利用极值法求取光强最大的一点gmax,然后确定一个阀值K=gmax-g(g取10-20),在 ...

  9. 灰度重心法提取中心线遇到的问题

    import cv2 img = cv2.imread("E:/tuku/2019-10-28_10_36_21_370.bmp",0) median = cv2.Gaussian ...

  10. 灰度重心法原理与实现

    转自:https://blog.csdn.net/moses1213/article/details/44679603 灰度重心法提取激光光条纹中心其实是将光条纹截面的灰度值分布中的质心记作为光条纹的 ...

最新文章

  1. html5 如何实现客户端验证上传文件的大小
  2. [测试]单元测试框架NUnit
  3. 【Qt】Qt之网格布局
  4. 新领导刚上任,哪些“傻事”千万不能干!
  5. Windows下安装BeautifulSoup
  6. leetcood学习笔记-58-最后一个单词的长度
  7. JavaSE基础知识学习-----泛型
  8. python paramiko使用_python paramiko 模块使用方法
  9. Javascript中类型的判断
  10. 如果一年只能两次旅游,你会选择什么季节去什么地方?
  11. [leetcode] 5331. 跳跃游戏 V
  12. 华为IPD 研发模式
  13. Word2010经常莫名其妙无法撤销
  14. afrog 发布新版 Release 1.3.6 漫天星辰
  15. 【信息系统项目管理师】【理解+题目】【信息系统与信息化】
  16. G6-Editor 编辑器入门使用教程
  17. react中使用微信jssdk分享总结
  18. Linux系统中如何创建NFS共享目录
  19. type接口和class的区别(类型和类)
  20. 字节跳动精准测试实践,SmartEye背后的设计逻辑

热门文章

  1. 从零开始学OpenCV(一)——OpenCV的安装
  2. 验证OpenCV安装是否成功工程测试模板
  3. 高分3号介绍及PIE使用
  4. 倒计时插件(及自动循环倒计时)代码
  5. 二叉平衡树AVL简介
  6. PPT 无法播放媒体/视频媒体不可用怎么解决
  7. Python实现简单的用户管理系统
  8. GIF工具大全(网站)
  9. matlab积分器,MATLAB_SIMULINK__积分器相关操作
  10. 一套数据中心弱电系统安全运维服务方案,完整版素材!