要达到的效果就是将线条尽量细化成单像素,按照论文上的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中线条细化算法的更多相关文章

  1. OpenCV学习(22) opencv中使用kmeans算法

    kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html 下面学习一下opencv中kmeans函数的使用.      首先我们 ...

  2. OpenCV学习(18) 细化算法(6)

    本章我们在学习一下基于索引表的细化算法. 假设要处理的图像为二值图,前景值为1,背景值为0. 索引表细化算法使用下面的8邻域表示法: 一个像素的8邻域,我们可以用8位二进制表示,比如下面的8邻域,表示 ...

  3. OpenCV学习(17) 细化算法(5)

    本章我们看下Pavlidis细化算法,参考资料http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/con ...

  4. OpenCV学习(16) 细化算法(4)

    本章我们学习Rosenfeld细化算法,参考资料:http://yunpan.cn/QGRjHbkLBzCrn 在开始学习算法之前,我们先看下连通分量,以及4连通性,8连通性的概念: http://w ...

  5. OpenCV学习(14) 细化算法(2)

          前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素.还有很多与此算法相似的细化算法,只是判断的条件不一样. ...

  6. OpenCV学习(13) 细化算法(1)

    程序编码参考经典的细化或者骨架算法文章: T. Y. Zhang and C. Y. Suen, "A fast parallel algorithm for thinning digita ...

  7. OpenCV中的SURF算法介绍

    SURF:speed up robust feature,翻译为快速鲁棒特征.首先就其中涉及到的特征点和描述符做一些简单的介绍: 特征点和描述符 特征点分为两类:狭义特征点和广义特征点.狭义特征点的位 ...

  8. OpenCV学习(35) OpenCV中的PCA算法

    PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html     对一副宽p.高q的二维灰度图,要完整表示该图像,需要m = ...

  9. OpenCV学习(15) 细化算法(3)

          本章我们学习一下Hilditch算法的基本原理,从网上找资料的时候,竟然发现两个有很大差别的算法描述,而且都叫Hilditch算法.不知道那一个才是正宗的,两个算法实现的效果接近,第一种算 ...

随机推荐

  1. Android 格式化分区命令

    mkfs.vfat  /dev/block/mmcblk0pxxxx           格式化某分区为vfat格式 busybox mkfs.vfat  /dev/block/mmcblk0pxxx ...

  2. hwclock和date源码分析

    一. hwclock 1.1 hwclock源码在哪里? util-linux 或者busybox 1.2 获取源码 git clone https://github.com/karelzak/uti ...

  3. Python 3.x 引入了函数注释

    Python 3.x 引入了函数注释,以增强函数的注释功能,下面是一个普通的自定义函数:   def dog(name, age, species):   return (name, age, spe ...

  4. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_09-前端显示当前用户-需求分析

    登陆成功 应该要显示用户的信息 cookie只存了用户的身份令牌.不包含用户的信息 拿着短令牌 请求认证服务获取到jwt.然后存储到sessionStorage 1.用户请求认证服务,登录成功. 2. ...

  5. jmeter 随机取一个值的方法

    1.添加用户自定义变量 在要用到随机值的地方写入 ${__RandomFromMultipleVars(1|2|0)} 例子: 效果:

  6. SpringCloud学习成长之十二 断路器监控

    在我的第四篇文章断路器讲述了如何使用断路器,并简单的介绍了下Hystrix Dashboard组件,这篇文章更加详细的介绍Hystrix Dashboard. 一.Hystrix Dashboard简 ...

  7. 无法连接App Store

    试了很多网上的方法,都没有效果,最后把hosts文件清空了,就可以了,不知道是为啥,同一份hosts文件在屋里能用,公司就不能用.

  8. jsplumb 流程图,常用功能配置记录

    前言: jsplumb 有2个版本一个Toolkit Edition(付费版),另外一个就是Community Edition(社区版本).Toolkit Edition版本功能集成的比较丰富,社区版 ...

  9. redcon, Redis兼容的服务器框架

    源代码名称:redcon 源代码网址:http://www.github.com/tidwall/redcon redcon源代码文档 redcon源代码下载 Git URL: 复制代码 git:// ...

  10. Go之gob包的使用

    gob包("encoding/gob")管理gob流——在encoder(编码器,也就是发送器)和decoder(解码器,也就是接受器)之间交换的字节流数据(gob 就是 go b ...