Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[第五次作业-问题2] 对于距离变换提取骨架的个人想法分享 #80

Open
aiboys opened this issue Nov 14, 2019 · 1 comment
Assignees
Labels

Comments

@aiboys
Copy link

aiboys commented Nov 14, 2019

关于图像距离变换得到骨架的个人想法分享

声明:

首先这仅仅是分享我个人的idea。刚认真学图像处理不久,这些问题我也是第一次遇到,但在群里发现有很多同学在询问,因此我选择把自己的想法分享出来,并且我也希望大家看到这篇能积极在issue里分享自己的idea,因为我就一菜鸟,大家厉害很多。其次我并不保证它是完全正确或者是最好的,如果同学们看到我的分享,我将十分感谢你能够指出其中的错误;并且如果你对我的想法有任何疑问,请留言,我会尽自己最大努力回答。

如果助教老师不允许发这种issue,我看到消息后会立马删除,不会有下次。我也只是觉得知识分享出来,大家一起讨论各自的方法,这样学到的东西会更多~~^_^


第一,关于距离变换的边界提取问题

关于边界提取,这里分为内边界外边界两种类型(在本次实验中我进行了两种边界的提取,并且基于此做了距离变换提取骨骼的实验)

以下是原图简单示意,黑色表示背景区域,绿色表示目标区域

originalpic

第二,对于内边界

内边界有两种提取方法。第一种是利用ppt上所写的原图减去(3,3)算子的腐蚀结果,就可以得到单像素边界;第二种方法是内边界跟踪法。这里我直接用ppt腐蚀方法实现,简单的示意图如下:

neibianjie

为了后续的距离变换以及局部极大操作,我这里将边界结果分三类像素考虑:(1)边界像素记作1;(2)背景区域记作-1;(3)目标区域边界内部记作0. 特别注意的是:此时边界像素依旧是原图的像素点

第三,对于外边界

外边界和内边界类似,也有如上跟踪法和非跟踪法提取。不同的是,它是利用一次膨胀操作,然后膨胀的结果减去原图,简单示意如下:

waibianjie

特别注意的是:此时蓝色区域不是原图的区域,是额外膨胀出来的部分内边界和外边界由于边界的不同,我在后续的操作加上了区分

第四,距离变换

在老师的上课讲解中,距离变换只需要关注目标区域,因此利用之前边界提取时保留的背景和目标区域flag可以加上判定区别;不然做出来的结果就是背景灰度很高(而不是0)。

第五,局部极大值

对于局部极大值的取法,我在网上发现有很多文章是关于此主题的。emmm能力有限,时间有限,我没选择用网上paper的方法,我只是简单利用了一下图片的一阶导数提取局部极大。

对于一个信号x,我们有下面的函数形式:

yijiedao1

对于一个有极值的函数,我们利用一阶导数就可以找到它。但是确定极大值不是导数等于0就可以,比如:

yijiedao2

对于这种信号函数,导数等于0肯定是不行的。因此我们需要找到一阶导数过零点,即图上蓝色点。这就要求左导数大于0,右导数小于0即可。

因此我按此进行试验,对于基于内边界得到的距离变化图,进过上述的一阶导数的要求,定义两个(3,3)卷积算子(分别得到左导数和右导数)(其实就是差分),结果如下:

distance_result_cor_edge_dayu0

嗯纳尼!?那里出现了问题?于是开始怀疑人生...

观察距离变化的图,我发现目标区域的“细纹”很窄,是不是有些地方一阶导并不完全满足上述过零要求?于是有示意图如下:

yijiedao3

灰色表示背景区域,蓝色为边界,粉红色为边界内部目标区域。右边是该种情况一维示意图(把-1置为0,因为它在求导数时被忽略)。可以看到在中间局部极大我们能够完美的取到该点。两边的0被忽略。但是有以下情况可能会出现:

yijiedao4

如果边界内部只有两列像素点,那么这时距离变换得到他们的灰度都是1,那么就会出现右边的信号情况。红色圈起来的三个点,我们在求导数时,发现右导数为0,;绿色圈起来的三个点,左导数为0.所以在判定时,由于需要考虑这种不是完全凹函数的情况,我们需要把过零点判定条件弱化一下,即 左导数大于等于0,右导数大于等于0,得到如下结果:

distance_result_cor_edge_dayudengyu0

可以看到,效果好了很多。反思:由于目标区域细纹太窄,极有可能很多地方只有四个像素点,那么就会出现上述在距离变换图一阶导数过零点不能完全满足左导数大于0,右导数小于0的局部极大判定。这将严重影响效果。其次,我们可以看到,最后的结果连通性还是不太好,这是为何呢?观察距离变换结果,发现距离变换的连通性也不好,由此想到,因为我们取了内边界,同样由于目标细纹太窄,极有可能有些地方只有两个像素值,这将导致求得边界时它们都被设为边界,因此距离变换后灰度为0,这就是连通性被破坏如此严重的原因。

于是我利用最开始提到的外边界的提取,经过一系列上述的操作,可以得到最终的骨架提取结果:

a63a99936b1a712310e8e55f2a452d1

最终效果还凑合~~~~

以上,希望能够帮助到一些同学。依然,如果你看到有错误或者任何疑惑,请留言,我将十分感谢。
在发这篇文章之前,想了很久到底要不要发,我也对自己的想法不是完全保证正确,如果误导同学怎么办~~
但我还是选择发了出来,因为有一句话"Sharing is the best way to learn.":) 。我想学到更多知识,并且由此来纠正自己错误的想法。闭门造车不可行。再次希望大家积极分享自己的idea。

@chendianhao
Copy link

很感谢这位同学的分享,我们也很鼓励这样的分享。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants