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

    OneDrive https://onedrive.live.com

  2. IO流概述

    作用: 处理设备之间的数据传输的 I: Input(输入) , O: Output(输出) 什么是输入和输出? 我们说输入和输出问题是站在内存的角度而言 , 如果我们程序读取硬盘上的数据那么就是输入 ...

  3. php生成的html 顶部有一空行的解决办法

    php生成的html 顶部有一空行的解决办法,但是生成的编译文件,即1d7c7a527b6335cc7a623305ca940e1findex.tpl.php就没有空行 比较两个HTML源代码一模一样 ...

  4. OSG 遍历fbx节点

    count:560 construction_worker 4294967295 osg::MatrixTransform1 Bip001 L Finger02 4294967295 osg::Mat ...

  5. MySQL之二进制日志

    一.Binlog日志格式 根据日志定义的格式不一样,可以分为Statement格式.Row格式或者MIXED格式 mysql5.6----> | binlog_format | STATEMEN ...

  6. java判断请求是否ajax异步请求

    java判断请求是否ajax异步请求   解决方法: if (request.getHeader("x-requested-with") != null && re ...

  7. windows的mysql无法启动 服务没有报告任何错误

    相信很多人都遇到过安装Mysql的时候出现各种各样的问题,今天小编就教大家解决window下mysql服务没有报告任何错误的情况下无法启动 的问题.本文所用的mysql版本是5.7以上版本,解决方法: ...

  8. 第一个php文件运行

    运行会发现报错,解决参考:写的很详细 http://blog.csdn.net/meegomeego/article/details/36020553

  9. 使用 Sublime + PlantUML 高效地画图

    转自 http://www.jianshu.com/p/e92a52770832

  10. KMeans聚类

    常用的聚类方法: ①分裂方法: K-Means算法(K-平均).K-MEDOIDS算法(K-中心点).CLARANS算法(基于选择的算法) ②层次分析方法: BIRCH算法(平衡迭代规约和聚类).CU ...