图像边缘含有图像形状的丰富信息,然而,图像边缘有时所含的像素点还是太多,很多情况下需要继续精简(比如,使用 ShapeContext 进行形状匹配),于是就出现一个问题:如何从图像边缘上提取出N个点,使这N个点最具有代表性呢?一个很直观的思路是:
(1)这N个点要在图像边缘上;
(2)最近邻的两点之间要尽量分散开。
如,图像为:
需要设计一个采样算法,使它得到下面的结果:
==== 实现 ====
1,将图像加载,转换为ImageU8类(参见《发布我的高性能纯C#图像处理基本类,顺便也挑战一下极限。:)》),方便下一步处理。
2,获得全部边缘像素的位置。
在《重新认识C#: 玩转指针》的一文基础上新添加一个扩展方法:
假设灰度值>0的点是边缘点,通过下面的两行代码就可以取得所有的边缘点:
2 img.ForEach((x, y, p) => { if ( * p > 0 ) points.Add( new Point(x, y)); });
简洁吧!
3,随机抽样
这一步参考了Jitendra Malik的实现,下面是他的matlab代码:
这段代码原理是:检查全部点对的距离,每次去除距离最小的点对中的一个点,直至剩下的点的数量达到要取样的点的数量N。如果点的总量M>>N,这样的操作是很费时间的,为了减少计算量,当M>>N时,随机取3N个点,对这3N个点进行操作即可。需要说明的是,即使M<3N,在具体抽样之前,也需要对样本进行随机打乱,这样才能使得后面删除点对中的某一个点这一行为具有随机性,不然的话,一条直线上的点恐怕会删的只剩尾部一个点。
下面是我的实现,实现方法和Jitendra Malik的略有不同,Jitendra Malik是使用矩阵来计算的,我使用List来计算:
其中:
本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2010/04/18/1714988.html如需转载请自行联系原作者
xiaotie 集异璧实验室(GEBLAB)