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算法.不知道那一个才是正宗的,两个算法实现的效果接近,第一种算 ...
随机推荐
- 关于form与表单提交操作的一切
原文链接:http://caibaojian.com/form.html 你知道,一个表单里面只要有form元素,如果没有给action加一个默认值,为空白的时候,当你刷新页面时,会弹出一个警告框提示 ...
- SQL SERVER SELECT语句中加锁选项的详细说明
共享锁(读锁)和排他锁(写锁) 共享锁(S锁):共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句. 如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能 ...
- Python与C/C++相互调用(python2 调c++那个试了ok)
一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...
- poi导出excel2007版本
/** * 导出excel2007版本 * * @param titles * 表头集合 * @param sheetNames * sheet名称 * @param datas * 数据集合 * @ ...
- SpringCloud学习成长之十三 断路器聚合监控
上一篇文章讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command.当我们有很多个服务的时候,这就需要聚合所以服务的Hystrix Dashboard的数据了.这就 ...
- nginx conf 文件
server { listen ; server_name local.light.com; index index.html index.htm index.php; root /home/wwwr ...
- 【ARTS】01_39_左耳听风-201900805~20190811
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 使用JavaScript实现量化策略并发执行
本文代码和文章发在FMZ发明者比特币量化交易平台上: 使用JavaScript实现量化策略并发执行--封装Go函数 - 发明者量化 https://www.fmz.com/digest-topic/3 ...
- nginx.conf文件配置明细详解
#etnx运行的用户和用户组 user nginx nginx; #工作进程数,建议设置为CPU的总核数 worker_processes ; #全局错误日志定义类型,日志等级从低到高依次为: #de ...
- mysql学习之join从句
一.join从句共有5种类型 内连接(inner join) 全外连接(full outer join) 左外连接(left outer join) 右外连接(right outer join) 交叉 ...