c++opencv中线条细化算法
要达到的效果就是将线条尽量细化成单像素,按照论文上的Hilditch算法试了一下,发现效果不好,于是自己尝试着写了一下细化的算法,基本原理就是从上下左右四个方向向内收缩。
1.先是根据图片中的原则确定了以下16种情况

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

3.修改了一下判断条件

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

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

最终实现的效果如下

对比图

对规则曲线的效果比较好


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

附上代码,测试了一天,终于弄完了,啊哈哈哈!然而后面还有更艰苦的路要走。加油!!!
//四周细化算法
void Refine(Mat& image)
{
int p[];
int top=, down=, right=, left=;
vector<Point> del;
int grayvalue = ;
int height = image.rows; //获取图像高度
int width = image.cols; //获取图像宽度
Mat *im = reinterpret_cast<Mat*>((void*)&image); //获取像素点信息
//上下收缩
for (int i = ; i < height-; i++)
{
for (int j = ; j < width-; j++)
{
grayvalue = Get_gray(im, j, i); //获取指定点灰度值
if (grayvalue != ) //判断中心点是否为前景
{
p[] = (Get_gray(im, j + , i) == ) ? : ;
p[] = (Get_gray(im, j + , i - ) == ) ? : ;
p[] = (Get_gray(im, j, i - ) == ) ? : ;
p[] = (Get_gray(im, j - , i - ) == ) ? : ;
p[] = (Get_gray(im, j - , i) == ) ? : ;
p[] = (Get_gray(im, j - , i + ) == ) ? : ;
p[] = (Get_gray(im, j, i + ) == ) ? : ;
p[] = (Get_gray(im, j + , i + ) == ) ? : ;
if (i < height - )
down = (Get_gray(im, j, i + ) == ) ? : ;
else
down = ;
// 横向直线
if (p[] && (p[] || p[] || p[] || p[]) && !(p[] || p[]) && p[] == && down)
{
del.push_back(Point(j, i));
}
if (p[] && (p[] || p[] || p[] || p[]) && !( p[] || p[]) && p[] == )
{
del.push_back(Point(j, i));
}
}
}
} for (int i = ; i < height - ; i++)
{
grayvalue = Get_gray(im, , i);
if (grayvalue != )
{
if ( Get_gray(im, , i - ) && Get_gray(im, , i - ) && Get_gray(im, , i + )== && Get_gray(im, , i)==) //上2,上1,右上1,下1=0,右1=0
{
del.push_back(Point(, i));
}
if (Get_gray(im, , i - ) == && Get_gray(im, , i + ) && Get_gray(im, , i) == && Get_gray(im, , i+))//上1=0,下1,右下1,右1=0,下2
{
del.push_back(Point(, i));
}
}
if (grayvalue != )
{
if (Get_gray(im, width - , i - ) && Get_gray(im, width - , i - ) && Get_gray(im, width - , i + ) == && Get_gray(im, width - , i) == ) //上2,上1,左上1,下1=0,左1=0
{
del.push_back(Point(width - , i));
}
if (Get_gray(im, width - , i - ) == && Get_gray(im, width - , i + ) && Get_gray(im, width - , i) == && Get_gray(im, width - , i + ))//上1=0,下1,左下1,左1=0,下2
{
del.push_back(Point(width - , i));
}
}
}
for (int i = ; i < del.size();i++)
{
uchar* data = image.ptr<uchar>(del[i].y);
data[del[i].x]=;
} //左右收缩
for (int i = ; i < height - ; i++)
{
for (int j = ; j < width - ; j++)
{
grayvalue = Get_gray(im, j, i); //获取指定点灰度值
if (grayvalue != ) //判断中心点是否为前景
{
p[] = (Get_gray(im, j + , i) == ) ? : ;
p[] = (Get_gray(im, j + , i - ) == ) ? : ;
p[] = (Get_gray(im, j, i - ) == ) ? : ;
p[] = (Get_gray(im, j - , i - ) == ) ? : ;
p[] = (Get_gray(im, j - , i) == ) ? : ;
p[] = (Get_gray(im, j - , i + ) == ) ? : ;
p[] = (Get_gray(im, j, i + ) == ) ? : ;
p[] = (Get_gray(im, j + , i + ) == ) ? : ;
if (j < width - )
right = (Get_gray(im, j + , i) == ) ? : ;
else
right = ; //竖直线
if (p[] && (p[] || p[] || p[] || p[]) && !(p[] || p[]) && p[] == && right)
{
del.push_back(Point(j, i));
}
if (p[] && (p[] || p[] || p[] || p[]) && !(p[] || p[]) && p[] == )
{
del.push_back(Point(j, i));
} }
}
} for (int j = ; j < width - ; j++)
{
grayvalue = Get_gray(im, j, );
if (grayvalue != )
{
if (Get_gray(im, j - , ) == && Get_gray(im, j + , ) && Get_gray(im, j + , ) && Get_gray(im, j, ) == && Get_gray(im, j+, )) //左1=0,右1,右2,下1=0,右下1
{
del.push_back(Point(j, ));
}
if (Get_gray(im, j - , ) && Get_gray(im, j+, )== && Get_gray(im, j, ) == && Get_gray(im, j-, ))//左1,右1=0,下1=0,左下1
{
del.push_back(Point(j, ));
}
}
}
for (int j = ; j < width - ; j++)
{
grayvalue = Get_gray(im, j, height-);
if (grayvalue != )
{
if (Get_gray(im, j - , height - ) == && Get_gray(im, j + , height - ) && Get_gray(im, j + , height - ) && Get_gray(im, j, height - ) == && Get_gray(im, j + , height - )) //左1=0,右1,右2,下1=0,右下1
{
del.push_back(Point(j, height - ));
}
if (Get_gray(im, j - , height - ) && Get_gray(im, j + , height - ) == && Get_gray(im, j, height - ) == && Get_gray(im, j - , height - ))//左1,右1=0,下1=0,左下1
{
del.push_back(Point(j, height - ));
}
}
} for (int i = ; i < del.size(); i++)
{
uchar* data = image.ptr<uchar>(del[i].y);
data[del[i].x] = ;
}
}
c++opencv中线条细化算法的更多相关文章
- OpenCV学习(22) opencv中使用kmeans算法
kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html 下面学习一下opencv中kmeans函数的使用. 首先我们 ...
- OpenCV学习(18) 细化算法(6)
本章我们在学习一下基于索引表的细化算法. 假设要处理的图像为二值图,前景值为1,背景值为0. 索引表细化算法使用下面的8邻域表示法: 一个像素的8邻域,我们可以用8位二进制表示,比如下面的8邻域,表示 ...
- OpenCV学习(17) 细化算法(5)
本章我们看下Pavlidis细化算法,参考资料http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/con ...
- OpenCV学习(16) 细化算法(4)
本章我们学习Rosenfeld细化算法,参考资料:http://yunpan.cn/QGRjHbkLBzCrn 在开始学习算法之前,我们先看下连通分量,以及4连通性,8连通性的概念: http://w ...
- OpenCV学习(14) 细化算法(2)
前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素.还有很多与此算法相似的细化算法,只是判断的条件不一样. ...
- OpenCV学习(13) 细化算法(1)
程序编码参考经典的细化或者骨架算法文章: T. Y. Zhang and C. Y. Suen, "A fast parallel algorithm for thinning digita ...
- OpenCV中的SURF算法介绍
SURF:speed up robust feature,翻译为快速鲁棒特征.首先就其中涉及到的特征点和描述符做一些简单的介绍: 特征点和描述符 特征点分为两类:狭义特征点和广义特征点.狭义特征点的位 ...
- OpenCV学习(35) OpenCV中的PCA算法
PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html 对一副宽p.高q的二维灰度图,要完整表示该图像,需要m = ...
- OpenCV学习(15) 细化算法(3)
本章我们学习一下Hilditch算法的基本原理,从网上找资料的时候,竟然发现两个有很大差别的算法描述,而且都叫Hilditch算法.不知道那一个才是正宗的,两个算法实现的效果接近,第一种算 ...
随机推荐
- wordpress插件开发从创建一个新的菜单开始
创建插件的目的 1.我们为什么要创建一个插件? IT界有一个知名的论调叫做不要造重复的轮子,如果有可能的话,你应该尽可能的从现有的网络资源上选择一个已有的插件来使用,而不是重新创造一个.它耗费的精力很 ...
- Qt编写自定义控件46-树状导航栏
一.前言 树状导航栏控件是所有控件中最牛逼最经典最厉害的一个,在很多购买者中,使用频率也是最高,因为该导航控件集合了非常多的展示效果,比如左侧图标+右侧箭头+元素前面的图标设置+各种颜色设置等,全部涵 ...
- Day5作业,商城+ATM机+后台管理
晚来了....东西太多,需要写的blog内容太多,re讲的渣渣,不明白为什么oldboy经常换老师,吐槽下吧,真心不爱了.... github地址在这:https://github.com/ccorz ...
- Python3之高阶函数filter
Python内建的filter()函数用于过滤序列 和map()一样,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是T ...
- 基于Visual Studio Code搭建Vue开发环境
安装node.js最新版 这里安装的是8.11.4版 image.png 更新npm至最新版 安装node.js后, npm默认版本为: 6.1.0 image.png 使用npm insta ...
- AWS 存储服务(三)
目录 AWS S3 业务场景 挑战 解决方案 S3的好处 S3 属性 存储桶 Buckets 对象 Object S3 特性 S3 操作 可用性和持久性 一致性 S3 定价策略 S3高级功能 存储级别 ...
- 在C/C++中常用的符号
C++中&和*的用法一直是非常让人头疼的难点,课本博客上讲这些知识点一般都是分开讲其用法的,没有详细的总结,导致我在这方面的知识结构格外混乱,在网上找到了一篇英文文章简单总结了这两个符号的一些 ...
- php 阿里云国内短信实例
调用:先去阿里云申请短信服务 $smsArr = array( "accessKeyId" => "", // key "accessKeySe ...
- 最新 新浪java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.新浪等10家互联网公司的校招Offer,因为某些自身原因最终选择了新浪.6.7月主要是做系统复习.项目复盘.LeetCode ...
- spring 中常用的两种事务配置方式
引用:http://blog.csdn.net/qh_java/article/details/51811533 引用:http://www.cnblogs.com/rushoooooo/archiv ...