最近一直研究基于灰度的边缘检测,搜索了好多博客文章,发现没有对Sobel算子解释的非常清晰明了的,对于我这种数学控,细节控,实在是无法忍受,所以索性自己查阅数学资料,研究一番,花了一周时间终于搞清楚了所有的困惑,分享给大家。这篇文章非常长,分成3个部分:实现原理,代码部分,数学部分,大家可以根据需要查看,如果能从头到尾啃完,相信一定有巨大收获!由于我不想把所有数学公式再打一遍了,所以直接上图了,请谅解
目录
1-5. 曼哈顿距离(Manhattan Distance )
图像由像素点组成的,在像素点的灰度变化剧烈的地方就可以被当作是边缘.
a.比较灰度
像素点一般来说可以有三种颜色表示,RGB,单独比较任何以中颜色,都不能表达图像某区域的变化.所以要比较灰度.
b.单像素点的最大变化值
每个像素点的灰度变化,是和周围像素点比较的结果,而且这个比较是有方向的. 某个方向也许变化不大,另一个方向变化或许很大. 必须选取变化最大的一个方向的数值,这个数值才有资格代表这个像素点的变化率. 从数学角度来说,灰度在某个方向的变化率,其实就是灰度在某个方向上的方向导数. 那么哪个方向的方向导数最大呢,是梯度的方向(注意,梯度是个向量),并且这个最大方向导数的绝对值,也就是最大的变化率的绝对值,等于梯度的模.
c.选出边缘
每个像素点的最大变化率都求出后,我们可以根据自己设定的阈值,进行筛选,得到最终的边缘.或者是按照这个变化率绝对值的大小,按照比例绘制粗细不同,颜色深浅不同的边缘轮廓.
具体的梯度公式和方向导数的推导证明请参考最后的“数学部分”,此处我们直接开始讨论像素的梯度计算.