@xiaojian233
2016-08-20T23:56:31.000000Z
字数 3517
阅读 1619
项目展示
“智能剪刀”( Intelligent Scissors) 是 Morten-son 和 Barrett 在 1995 年提出来的一种图像分割交互工具,它可用于 2D 图像分割 ,通过这个工具, 用户可以容易且精确地在图像中勾画出感兴趣的区域 ROI( Region Of Interest) 。[3]
图像区域耗费值(Image Local Cost) 是图像边界提取的依据。
Morten-son 和 Barrett 先后在1995年发表论文[1] 和 1998年发表论文[2] 。在两次的论文中,对于ILC 的取值有点不一样。
现在一般而言,ILC 的取值一共由六项图像特征值加权和[2],分别是:
而在论文[1] 中,仅由前面三项决定。
设l(p,q)
表示ILC 的值,p 表示像素,q表示p 的相邻像素。(p、q 是一维的矢量,表示像素在图像中的坐标)
那么在论文[1] 中的计算如下:
其中,各个变量值如下:
名 | 说明 |
---|---|
fZ(q) | 拉普拉斯交叉零点 |
fD(p, q) | 梯度值方向 |
fG(q) | 梯度值 |
WZ | 加权值,0.43 |
WD | 加权值,0.43 |
WG | 加权值,0.14 |
在论文[2] 中,这个公式的计算如下:
名 | 说明 |
---|---|
fZ(q) | 拉普拉斯交叉零点 |
fD(p, q) | 梯度值方向 |
fG(q) | 梯度值 |
fP(q) | 边界像素值 |
fI(q) | 内部像素值 |
fO(q) | 外部像素值 |
WZ | 加权值,0.3 |
WD | 加权值,0.1 |
WG | 加权值,0.3 |
WP | 加权值,0.1 |
WI | 加权值,0.1 |
WO | 加权值,0.1 |
fZ的计算如下:
其中 IL 表示的是图像的拉普拉斯变换值。
IL 的计算是使用如下模板对图像做卷积:
0 1 0
1 -4 1
0 1 0
(对图像进行二阶求导)
令 IX 和 IY 表示像素在 x 和 y 方向的梯度,则梯度 G 的计算如下:
为使高梯度产生低能量,fG的计算定义如下:
如果q 是p 的对角相邻点,那么fG不变。如果q 是p 的水平或者垂直相邻点,那么fG除以根号2
其中IX 和 IY 的计算如下:
IX(i, j) = IX(i+1, j) -IX(i, j)
IY(i, j) = IX(i, j+1) - IX(i, j)
i, j 是像素的坐标
假设 D(p) 表示的是像素点 p 的梯度方向,而 D'(p) 表示的与梯度方向垂直的向量(顺时针旋转90° 得来),那么 D(p) 和 D'(p) 的计算如下:
D(p) = [ IX(p), IY(p) ]
D'(p) = [ IY(p), -IY(p) ]
*最后要归一化向量
fD这个在两篇论文里面计算的方式不一样。
在论文[1] 中如下:
*cos[]-1 表示的是反余弦函数
其中dp 和 dq 的计算如下:
在论文[2] 中这个公式变为:
L 的计算也变为:
*|| p - q || 表示的泛数,这里是两个向量差的平方和再开根
*原来的论文中还有一段fD 计算的举例,我验算了好久,才发现,好像坐标轴是
^
-- | -->
这么放的………………可是我们是在处理图像呀……摔~
*I(p) 表示该坐标的像素值
内部像素值和外部像素值分别是在像素点的梯度方向和反方向的偏移像素值。
k是一个恒定距离值(由用户定义)。而偏移的像素也可以是最近的像素值(默认)或由周围的四个像素双线性插值得来。
在计算出ILC 值后,就可以计算最短路径生成算法了。
这个算法在论文中有很详细的解释。
*算法要认真阅读
从这里开始整理一下实现的思路,注意到整个算法的核心是计算ILC 值和路径的计算。认真分析ILC 值得计算,发现有些图像特征值的计算是不依赖于p 、 q 两点的关系的,那么对于这个特征值,有必要进行预处理。
首先对整张图像预处理计算IL, 然后用来计算fZ的值。由于在后续的计算过程中不需要重复使用到IL,所以可以直接在同一个内存空间上先后完成IL和fZ的计算。
fG和D'(p) 都需要先计算出IX 和 IY,所以这两个值可以同时完成计算。
但是fG 并不完全依赖于q 点,所以在计算ILC 值还要判断p, q 点的位置关系。
fP 就等于p 点的像素值,直接取值就好。
fI 和 fO 的计算都很简单,在计算ILC 的时候,实时计算就行。实现版本如下,采用最近邻像素的方式:
在前面的计算中,D'(p) 已经预处理了,所以这里直接计算fD的值就好。
上面的计算已经把各个图像的特征值都求出来了,这里直接进行加权求和就可以。
但是加权fG的时候,需要注意,还要对照p、 q 关系决定是不是需要除以根号2.
输入种子点,然后种子点到所有的像素的最短路径,记录起来。
在opencv 中,可以注册鼠标的回调函数,当预处理后,就可以快速地表现出效果了。
但是在实际实现的过程中,不知道哪里出问题了,导致这个效果非常差,而且计算的消耗也很大,支撑不起多次的重复计算,所以我重新搜索资料,然后看到一篇康奈尔大学的课程教学文章,见[4]
在[4] 中,依然是在论文[1] 的基础上实现的,只不过是改变了计算图像耗费值的方式。
经过尝试,发现这样的实现更加快速,效果也更好。
在【4】 中,对cost function 的计算做了一点更改,但是效果更好。
将一个像素描述如图所示:
其中(i,j)是像素点,各个连接表示它与八领域相连的通路,为了表示方便,分别以0-7编号各个连接(link)
其中0,2,4,6 是垂直和平行连接,1,3,5,7是对角连接。
设D(link i)代表当前像素到它领域的连接的权重。
那么
D(link1) = |I(i+1,j)-I(i,j-1)|/sqrt(2)
其中 I
表示当前的像素值。
D(link1)是对角连接的计算方式,3,5,7可以同理推出。
D(link0) = | I(i-1,j)+I(i-1,j-1)-I(i+1,j)-I(i+1,j-1) |/4
D(link0) 是垂直和平行连接的计算方式,2,4,6可以同理推出。
而对于 cost function 的定义如下:
cost(link)=(maxD-D(link))*length(link).
maxD 是 D 的最大值,length(link)就是连接的长度,定义如下:
length(link) = 1; //link 是平直或垂直连接
length(link) = sqrt2;//link 是对角连接
如 length(link0) = 1, length(link1) = sqrt2
后面的依然是计算最小的路径,与前文内容完全一样(但是算法要好好看)
相比之前,这个版本的实现较之前面的更加容易,只需要一次粗暴地计算cost 就可以了。因为计算最小路径时需要重复使用cost,那么做预处理就很有必要,结果是大概如下:
怎么实现就见仁见智了,在此按下不表。
每次选择种子点的话,都要重新计算一遍最小路径,主要的耗时也是在这里。然而怎么去做优化,暂时没有头绪。
我觉得【4】简直太良心了,有详细的说明步骤,详细的理论解答,详细的to do list,还提供了一个简单的源程序。
跑一下,大概就能明白最后的结果应该是怎么样的了。
下面放下实验的结果:
康奈尔大学的计算结果:
论文的实现结果:
(我不知道到底哪里出了问题,导致结果偏差这么严重)
最后,程序可以在github上得到:xiaosa233
(Compute Vision /Image Setmentation)
【参考资料】
[1] Mortensen E N, Barrett W A. Intelligent scissors for image composition[C]//Proceedings of the 22nd annual conference on Computer graphics and interactive techniques. ACM, 1995: 191-198.
[2] Mortensen E N, Barrett W A. Interactive segmentation with intelligent scissors[J]. Graphical models and image processing, 1998, 60(5): 349-384.
[3] 李志鹏. 智能剪刀在进入式漫游中的应用[J]. 计算机与数字工程, 2010, 38(3): 143-145.
[4] CS 4670/5670, Project 1: Image Scissors
--END--
Email : li.xiaojian233@qq.com