优秀的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. iOS开发之UIMenuController的基本使用
  2. 读书计划清单之碎碎念
  3. 超级实用sap table
  4. 数据源(连接池)的作用
  5. 智能时代 软件赋能——2017中国软件技术大会
  6. 单调谐回路谐振放大器等效电路分析_手把手教你如何分析三极管电路
  7. cd1101d 树形dp
  8. 类型,对象,线程栈和托管堆在运行时的相互关系(一)。
  9. 23. PE结构-PE详解之输出表(导出表)
  10. Worktile协同特色之二:任务看板管理
  11. java 数字的进制转换
  12. Oracle HA 之 SERVICE和DRM实战
  13. Ubuntu 磁盘自动挂载解决
  14. Linux下配置MySQL免安装版
  15. http awstats安装
  16. linux 文件与目录操作
  17. 两款导航网站源码 支持自动收录、自动审核、自动检测友链功能.
  18. 如何实时捕捉社会热点?微博热搜数据监测系统-API接口
  19. 【建议收藏】10个适合程序员逛的在线社区
  20. lisp画弯箭头_在CAD中直接用命令画箭头

热门文章

  1. ubuntu 下文件/文件夹 比较工具 DiffMerge
  2. matlab生成浮雕灰度图,将照片做成浮雕灰度图
  3. 【解决方法】Socket服务端退出之后端口依旧被占用
  4. 中国十大骨干网,了解互联网的真实结构
  5. 深入理解 JVM 垃圾回收机制及其实现原理
  6. 【radon】图像的radon变换matlab仿真
  7. 超级鹰+selenium规避检测模拟登录12306
  8. 如何制作一份高大上的学术PPT?
  9. 网络七层协议结构分析图
  10. U8采购入库单参照到货单查不到内容