c++opencv中线条细化算法

要达到的效果就是将线条尽量细化成单像素,按照论文上的Hilditch算法试了一下,发现效果不好,于是自己尝试着写了一下细化的算法,基本原理就是从上下左右四个方向向内收缩。

1.先是根据图片中的原则确定了以下16种情况

2.调试过后发现,迭代次数多了之后,原来连接着的线条会断开,分析原因如下图

3.修改了一下判断条件

4.调试过后发现还是会出现断的地方,再次分析原因如下图

5.又加了判断条件,如下图

最终实现的效果如下

 

对比图

对规则曲线的效果比较好

但是圆的效果不太好,有待改进

附上代码,测试了一天,终于弄完了,啊哈哈哈!然而后面还有更艰苦的路要走。加油!!!

  1 //四周细化算法
  2 void Refine(Mat& image)
  3 {
  4     int p[8];
  5     int top=1, down=1, right=1, left=1;
  6     vector<Point> del;
  7     int grayvalue = 0;
  8     int height = image.rows;   //获取图像高度
  9     int width = image.cols;       //获取图像宽度
 10     Mat *im = reinterpret_cast<Mat*>((void*)&image);    //获取像素点信息
 11     //上下收缩
 12     for (int i = 1; i < height-1; i++)
 13     {
 14         for (int j = 1; j < width-1; j++)
 15         {
 16             grayvalue = Get_gray(im, j, i);  //获取指定点灰度值
 17             if (grayvalue != 0)   //判断中心点是否为前景
 18             {
 19                 p[0] = (Get_gray(im, j + 1, i) == 0) ? 0 : 1;
 20                 p[1] = (Get_gray(im, j + 1, i - 1) == 0) ? 0 : 1;
 21                 p[2] = (Get_gray(im, j, i - 1) == 0) ? 0 : 1;
 22                 p[3] = (Get_gray(im, j - 1, i - 1) == 0) ? 0 : 1;
 23                 p[4] = (Get_gray(im, j - 1, i) == 0) ? 0 : 1;
 24                 p[5] = (Get_gray(im, j - 1, i + 1) == 0) ? 0 : 1;
 25                 p[6] = (Get_gray(im, j, i + 1) == 0) ? 0 : 1;
 26                 p[7] = (Get_gray(im, j + 1, i + 1) == 0) ? 0 : 1;
 27                 if (i < height - 2)
 28                     down = (Get_gray(im, j, i + 2) == 0) ? 0 : 1;
 29                 else
 30                     down = 1;
 31                 //  横向直线
 32                 if (p[6] && (p[5] || p[7] || p[0] || p[4]) && !(p[1] || p[3]) && p[2] == 0 && down)
 33                 {
 34                     del.push_back(Point(j, i));
 35                 }
 36                 if (p[2] && (p[1] || p[3] || p[0] || p[4]) && !( p[5] || p[7]) && p[6] == 0)
 37                 {
 38                     del.push_back(Point(j, i));
 39                 }
 40             }
 41         }
 42     }
 43
 44     for (int i = 1; i < height - 2; i++)
 45     {
 46         grayvalue = Get_gray(im, 0, i);
 47         if (grayvalue != 0)
 48         {
 49             if ( Get_gray(im, 0, i - 1) && Get_gray(im, 1, i - 1) && Get_gray(im, 0, i + 1)==0 && Get_gray(im, 1, i)==0) //上2,上1,右上1,下1=0,右1=0
 50             {
 51                 del.push_back(Point(0, i));
 52             }
 53             if (Get_gray(im, 0, i - 1) == 0 && Get_gray(im, 1, i + 1) && Get_gray(im, 1, i) == 0 && Get_gray(im, 0, i+2))//上1=0,下1,右下1,右1=0,下2
 54             {
 55                 del.push_back(Point(0, i));
 56             }
 57         }
 58         if (grayvalue != 0)
 59         {
 60             if (Get_gray(im, width - 1, i - 1) && Get_gray(im, width - 2, i - 1) && Get_gray(im, width - 1, i + 1) == 0 && Get_gray(im, width - 2, i) == 0) //上2,上1,左上1,下1=0,左1=0
 61             {
 62                 del.push_back(Point(width - 1, i));
 63             }
 64             if (Get_gray(im, width - 1, i - 1) == 0 && Get_gray(im, width - 2, i + 1) && Get_gray(im, width - 2, i) == 0 && Get_gray(im, width - 1, i + 2))//上1=0,下1,左下1,左1=0,下2
 65             {
 66                 del.push_back(Point(width - 1, i));
 67             }
 68         }
 69     }
 70     for (int i = 0; i < del.size();i++)
 71     {
 72         uchar* data = image.ptr<uchar>(del[i].y);
 73         data[del[i].x]=0;
 74     }
 75
 76     //左右收缩
 77     for (int i = 1; i < height - 1; i++)
 78     {
 79         for (int j = 1; j < width - 1; j++)
 80         {
 81             grayvalue = Get_gray(im, j, i);  //获取指定点灰度值
 82             if (grayvalue != 0)   //判断中心点是否为前景
 83             {
 84                 p[0] = (Get_gray(im, j + 1, i) == 0) ? 0 : 1;
 85                 p[1] = (Get_gray(im, j + 1, i - 1) == 0) ? 0 : 1;
 86                 p[2] = (Get_gray(im, j, i - 1) == 0) ? 0 : 1;
 87                 p[3] = (Get_gray(im, j - 1, i - 1) == 0) ? 0 : 1;
 88                 p[4] = (Get_gray(im, j - 1, i) == 0) ? 0 : 1;
 89                 p[5] = (Get_gray(im, j - 1, i + 1) == 0) ? 0 : 1;
 90                 p[6] = (Get_gray(im, j, i + 1) == 0) ? 0 : 1;
 91                 p[7] = (Get_gray(im, j + 1, i + 1) == 0) ? 0 : 1;
 92                 if (j < width - 2)
 93                     right = (Get_gray(im, j + 2, i) == 0) ? 0 : 1;
 94                 else
 95                     right = 1;
 96
 97
 98                 //竖直线
 99                 if (p[0] && (p[1] || p[7] || p[2] || p[6]) && !(p[3] || p[5]) && p[4] == 0 && right)
100                 {
101                     del.push_back(Point(j, i));
102                 }
103                 if (p[4] && (p[3] || p[5] || p[2] || p[6]) && !(p[1] || p[7]) && p[0] == 0)
104                 {
105                     del.push_back(Point(j, i));
106                 }
107
108             }
109         }
110     }
111
112     for (int j = 1; j < width - 2; j++)
113     {
114         grayvalue = Get_gray(im, j, 0);
115         if (grayvalue != 0)
116         {
117             if (Get_gray(im, j - 1, 0) == 0 && Get_gray(im, j + 1, 0) && Get_gray(im, j + 2, 0) && Get_gray(im, j, 1) == 0 && Get_gray(im, j+1, 1)) //左1=0,右1,右2,下1=0,右下1
118             {
119                 del.push_back(Point(j, 0));
120             }
121             if (Get_gray(im, j - 1, 0) && Get_gray(im, j+1, 0)==0 && Get_gray(im, j, 1) == 0 && Get_gray(im, j-1, 1))//左1,右1=0,下1=0,左下1
122             {
123                 del.push_back(Point(j, 0));
124             }
125         }
126     }
127     for (int j = 1; j < width - 2; j++)
128     {
129         grayvalue = Get_gray(im, j, height-1);
130         if (grayvalue != 0)
131         {
132             if (Get_gray(im, j - 1, height - 1) == 0 && Get_gray(im, j + 1, height - 1) && Get_gray(im, j + 2, height - 1) && Get_gray(im, j, height - 2) == 0 && Get_gray(im, j + 1, height - 2)) //左1=0,右1,右2,下1=0,右下1
133             {
134                 del.push_back(Point(j, height - 1));
135             }
136             if (Get_gray(im, j - 1, height - 1) && Get_gray(im, j + 1, height - 1) == 0 && Get_gray(im, j, height - 2) == 0 && Get_gray(im, j - 1, height - 2))//左1,右1=0,下1=0,左下1
137             {
138                 del.push_back(Point(j, height - 1));
139             }
140         }
141     }
142
143     for (int i = 0; i < del.size(); i++)
144     {
145         uchar* data = image.ptr<uchar>(del[i].y);
146         data[del[i].x] = 0;
147     }
148 }

原文地址:https://www.cnblogs.com/Summerio/p/8284602.html

时间: 2024-11-13 10:13:50

c++opencv中线条细化算法的相关文章

opencv中使用 SURF算法匹配的遇到的问题

错误 1 error LNK2019: 无法解析的外部符号 "public: __thiscall cv::SURF::SURF(double,int,int,bool,bool)" ([email protected]@@[email protected][email protected]),该符号在函数 _main 中被引用错误 2 error LNK1120: 1 个无法解析的外部命令 解决方法:缺少函数库.在连接器--输入--附加依赖项里面加上两个库:opencv_nonfre

OpenCV中Delaunay三角网算法例子

#include <opencv2/opencv.hpp> #include <vector> using namespace cv; using namespace std; typedef struct _TRIANGLE_DESC_ { Point pt1, pt2, pt3; _TRIANGLE_DESC_(const Point _pt1, const Point _pt2, const Point _pt3): pt1(_pt1), pt2(_pt2), pt3(_pt

图像处理之 opencv 学习---opencv 中的常用算法

http://blog.csdn.net/lindazhou2005/article/details/1534234 文中有提到鲁棒性 http://blog.csdn.net/chary8088/article/details/24935559

OpenCV中的SVM参数优化

OpenCV中的SVM参数优化 标签: svm参数优化opencv SVMSVR参数优化CvSVMopencv CvSVM 2014-08-19 10:31 2995人阅读 评论(8) 收藏 举报  分类: 机器学习(11)  opencv(18)  版权声明:本文为博主原创文章,未经博主允许不得转载. SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最常用的是用于分类,不过SVM也可以用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,OpenC

opencv3中的机器学习算法之:EM算法

不同于其它的机器学习模型,EM算法是一种非监督的学习算法,它的输入数据事先不需要进行标注.相反,该算法从给定的样本集中,能计算出高斯混和参数的最大似然估计.也能得到每个样本对应的标注值,类似于kmeans聚类(输入样本数据,输出样本数据的标注).实际上,高斯混和模型GMM和kmeans都是EM算法的应用. 在opencv3.0中,EM算法的函数是trainEM,函数原型为: bool trainEM(InputArray samples, OutputArray logLikelihoods=n

OpenCV中的SVM參数优化

SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最经常使用的是用于分类,只是SVM也能够用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,opencv中自然也是有集成好了,我们能够直接调用.OpenCV中的SVM算法是基于LibSVM软件包开发的,LibSVM是台湾大学林智仁(Lin Chih-Jen)等开发设计的一个简单.易于使用和高速有效的SVM模式识别与回归的软件包. 网上讲opencv中SVM使用的文章有非常多,但讲SVM參数优化的文章却

[OpenCV-Python] OpenCV 中的图像处理 部分 IV (六)

部分 IVOpenCV 中的图像处理 23 图像变换 23.1 傅里叶变换目标本小节我们将要学习: ? 使用 OpenCV 对图像进行傅里叶变换 ? 使用 Numpy 中 FFT(快速傅里叶变换)函数 ? 傅里叶变换的一些用处 ? 我们将要学习的函数有:cv2.dft(),cv2.idft() 等原理 傅里叶变换经常被用来分析不同滤波器的频率特性.我们可以使用 2D 离散傅里叶变换 (DFT) 分析图像的频域特性.实现 DFT 的一个快速算法被称为快速傅里叶变换(FFT).关于傅里叶变换的细节知

[OpenCV-Python] OpenCV 中图像特征提取与描述 部分 V (一)

部分 V图像特征提取与描述 29 理解图像特征 目标本节我会试着帮你理解什么是图像特征,为什么图像特征很重要,为什么角点很重要等.29.1 解释 我相信你们大多数人都玩过拼图游戏吧.首先你们拿到一张图片的一堆碎片,要做的就是把这些碎片以正确的方式排列起来从而重建这幅图像.问题是,你怎样做到的呢?如果把你做游戏的原理写成计算机程序,那计算机就也会玩拼图游戏了.如果计算机可以玩拼图,我们就可以给计算机一大堆自然图片,然后就可以让计算机把它拼成一张大图了.如果计算机可以自动拼接自然图片,那我们是不是可

[OpenCV-Python] OpenCV 中图像特征提取与描述 部分 V (二)

部分 V图像特征提取与描述 34 角点检测的 FAST 算法 目标 ? 理解 FAST 算法的基础 ? 使用 OpenCV 中的 FAST 算法相关函数进行角点检测原理 我们前面学习了几个特征检测器,它们大多数效果都很好.但是从实时处理的角度来看,这些算法都不够快.一个最好例子就是 SLAM(同步定位与地图构建),移动机器人,它们的计算资源非常有限.为了解决这个问题,Edward_Rosten 和 Tom_Drummond 在 2006 年提出里 FAST 算法.我们下面将会对此算法进行一个简单