要达到的效果就是将线条尽量细化成单像素,按照论文上的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. React拾遗(下)

    reconciliation(协调算法) react用于更新DOM的算法.基于两点假设,实现了一个启发的O(n)算法: 两个不同类型的元素将产生不同的树. 通过渲染器附带key属性,开发者可以示意哪些 ...

  2. LC 516. Longest Palindromic Subsequence

    Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...

  3. setShadpwLayer实现阴影效果

    package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.*; imp ...

  4. vmware安装centos7.5、配置网卡、环境配置

    1.vmware安装centos7.5虚拟机    参考连接: https://blog.csdn.net/guo_ridgepole/article/details/78973763 可能遇到的问题 ...

  5. Yarn使用笔记

    1.安装需要下载安装包(这里只介绍windows系统的安装) 安装成功,会如图提示! 版本号:Yarn安装包-yarn-0.24.6 安装包下载地址:链接:http://pan.baidu.com/s ...

  6. iOS面试题超全!

    之前看了很多面试题,感觉要不是不够就是过于冗余,于是我将网上的一些面试题进行了删减和重排,现在分享给大家.(题目来源于网络,侵删) 1. Object-c的类可以多重继承么?可以实现多个接口么?Cat ...

  7. mybatis传入map任意表增删改查,分页过滤字段

    <!--根据实体参数查询 --> <select id="selectBaseList" resultType="java.util.HashMap&q ...

  8. 用MOQ来Mock静态方法的 2种方法(含Moq和Fakes的配合使用)

    Moq是无法直接模拟静态方法的,解决方式有两种: 1.需要修改正式代码,在源代码中建一个新的方法把静态方法包起来,调用的时候源代码调用时调用新方法而不是原来的静态方法. 在测试的时候,Mock掉这个新 ...

  9. VLOOKUP函数 from Excel

    1.VLOOKUP函数是Excel中的一个纵向查找函数,它与LOOKUP函数和HLOOKUP函数属于一类函数,在工作中都有广泛应用,例如可以用来核对数据,多个表格之间快速导入数据等函数功能.功能是按列 ...

  10. 最新 创蓝253java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.创蓝253等10家互联网公司的校招Offer,因为某些自身原因最终选择了创蓝253.6.7月主要是做系统复习.项目复盘.Le ...