翻译自: Edge Detection in Computer Visiongit
边缘检测是计算机视觉中最重要的概念之一。这是一个很直观的概念,在一个图像上运行图像检测应该只输出边缘,与素描比较类似。个人目标不只是清晰地解释边缘检测是怎样工做的,同时也提供一个新而又容易的方法只须要最小工做来明显地提升边缘检测。github
截图1: 算法
经过得到这些边缘,许多计算机算法才得以有可能实现,由于在一个场景中边缘包含着绝大部分(至少不少)的信息。app
举个例子,咱们都记得 Windows XP
的那个绿色小山坡和蓝色天空的背景。jsp
截图2: 函数
当咱们的大脑试图去理解这个场景时,咱们知道这是草地,看起来很统一。而后,咱们看到了飘着些许白云的天空。这些对象的每个都是分离的,并且它们之间有一个边缘。这就是场景中为何绝大部分的信息存在与边缘中。学习
这也是为何边缘检测是计算机视觉中的重要概念。经过把图像减小到只剩下边缘,使得对于许多算法更容易识别、学习、或者处理场景。测试
边缘检测的大多数是基于滤波的。一般来讲,滤波是一个消除的动做。好比:过滤水,是消除寄生虫。类似地,当咱们尝试找到图像边缘时,我是在尝试消除掉除图像边缘以外的东西。优化
消除那些不是有用的边缘的图像部分,而留下合适的边缘也是困难所在。我怎么知道这是否是有用的边缘,好比,我对 Windows XP 背景运行 Canny edge dectector 程序,效果以下。url
截图3:
你能看到那些小草的细小刀刃似的边缘,这很让人讨厌,并且没有真正提供有用的信息。甚至那些云朵也不是很是清晰。如今,你能在大多数的 Canny edge dectector
上设置一些边界,这些边界设置了阈值(或者 非极大值抑制),全部的边缘必须知足这个阈值才能划分为“重要的”边缘。与其在 Canny edge
的阈值上区分,不如咱们更普遍地来谈谈,而且搭建几个滤波器。
高斯滤波器
是边缘检测最基础的滤波器之一,虽然还有其余的,可是高斯滤波器
会贯穿这篇文章。高斯滤波器
,正如其名,是一个基于高斯分布的滤波器。
截图4:
它看起来像一个抛物线(除了在二维的状况)。经过矩阵乘法,高斯滤波器
能被应用到每个像素上。它实现的是混合效果,让最中心的像素尽可能小基于它相邻的像素。举个例子,如对个人猫的图像运行一个均匀分布的高斯滤波器,我可以获得下面的图像:
Mew
的图片截图5:
Mew
的图片应用高斯滤波
截图6:
你能够看到图像变得模糊了,高斯滤波器就是获取全部像素,让像素值的成分是与相邻像素有关。
为了让高斯滤波器在边缘检测中有效,咱们可使用从 x
和 y
A Computational Approach to Edge Detection 方面求导出来的高斯滤波器。这也许听起来有点反直觉,或者不知所谓,可是若是咱们看到这种导数高斯滤波器的图像,这种想法就很清晰了。
截图7:
当你把一个高斯的 x
和 y
份量求导后,一个大的波峰和波谷就出现了。若是你明白导数,思考下这种状况,你应该能很快想到。因为高斯函数峰上数值上的巨大变化,从而致使了高斯导数波峰和波谷的出现。
若是咱们把上面的写成代码,那至关直接(至少对于 Matlab
和 Python
来讲):
% Takes the derivative of a 5x5 gaussian, with a sigma [hx, hy] = gradient(fspecial('gaussian',[5 5],sigma));
这就是了,一行代码就能获得咱们所想要的高斯,而后对 x
和 y
份量求导。
咱们已经有了两个高斯滤波器
,咱们把他们应用到图像中。咱们一样使用非极大值限制,即若是不是极大值的话,就把像素值设置为0
。换种说法就是消除噪声。
应用滤波器的代码以下:
% Convert an image to double for increased precision img = double(img); % Find two derived gaussians with respect to x and y [hx, hy] = gradient(fspecial('gaussian',[5 5],sigma)); % Run the filters over the image, generating a filtered image % Leaves x edges gx = double(imfilter(img,hx,'replicate', 'conv')); % Leaves y edges gy = double(imfilter(img,hy,'replicate', 'conv')); % Take the absolute value, and combine the x and y edges mag = sqrt((gx .* gx) + (gy .* gy)); % Use non-maxima suppression [mag, ] = max(mag, [], 3);
若是咱们将它应用个人猫的一张图片,我咱们就获得一下的图片:
截图8:
有趣地是,咱们一样也能这种方法应用到 RGB 图像上去,一样也会获得彩色的边缘。
RGB
图片应用滤波器截图9:
这两张图片应该都能表明像素和它相邻之间像素的颜色的差别,只不过彩色图像有3
个通道:RGB
,而黑白图像只有1
个通道。(原译文翻译为层, 这里改成通道)
为何要限制咱们本身仅仅使用绝对的 x
和 y
方向的滤波器呢?让咱们也来构建一些方向滤波器。这个方法(或多或少)来源于 Freeman
和 Adelson
的《The design and use of steerable filters》 论文,这个想法使咱们可以把咱们的高斯滤波器
放置在不一样的方向。
根本上,咱们把咱们的高斯滤波器
放置到不一样的方向上去,以基于与高斯相关的边缘的角度来建立不一样数值。好比,若是咱们把高斯函数放置到45
度,应用到45
度角的图像上,应该能够比在0
度的高斯函数获得更高的数量级。
在这种状况下,我生成了几种不一样的方向滤波器:
截图10:
顶部行x份量,底部行y份量
各类各样的高斯函数产生了相对于 x
和 y
份量上的90
、45
、-45
和 22.5
度的滤波器。这也就产生了不一样的边缘大小,尽管这些滤波器应该检测出相近的边缘。
截图11:
我使用的代码与单个滤波器使用的代码几乎相同,可是我不一样以往地把他们混合在一块儿。它看起来有点杂乱,可是我经过让我运行每一个滤波器表达更明白来尽量使它看起来更清晰。
% Create four filters [hx, hy] = gradient(fspecial('gaussian',[5 5],sigma)); [hx1, hy1] = altOrientFilter1(hx, hy); [hx2, hy2] = altOrientFilter2(hx, hy); [hx3, hy3] = altOrientFilter3(hx, hy); % Run first gaussian filter on image gx = double(imfilter(img,hx,'replicate', 'conv')); gy = double(imfilter(img,hy,'replicate', 'conv')); % Run second gaussian filter on image gx1 = double(imfilter(img,hx1,'replicate', 'conv')); gy1 = double(imfilter(img,hy1,'replicate', 'conv')); % Run third gaussian filter on image gx2 = double(imfilter(img,hx2,'replicate', 'conv')); gy2 = double(imfilter(img,hy2,'replicate', 'conv')); % Run fourth gaussian filter on image gx3 = double(imfilter(img,hx3,'replicate', 'conv')); gy3 = double(imfilter(img,hy3,'replicate', 'conv')); % Merge all filters squareGD = (gx .* gx) + (gy .* gy); squareGD = squareGD + (gx1 .* gx1) + (gy1 .* gy1); squareGD = squareGD + (gx2 .* gx2) + (gy2 .* gy2); squareGD = squareGD + (gx3 .* gx3) + (gy3 .* gy3); % Run non-maxima supression [mag, ] = max(sqrt(squareGD), [], 3);
若是你靠近点看的话,你能看到数量大小的不一样,特别是那些皱纹。若是咱们混合了全部图像,咱们就能获得一张轻微较好的边缘检测。
截图12:
方向滤波器和非方向滤波器之间并无很大的不一样,可是咱们也应该看到多种方向的结果有些许的提升。
过去两年,我在不一样的彩色域上作了大量的测试和实验。特别地是,Lab 彩色域
(Lab color space
)是另外一种描述图像的方式。好比,咱们知道的 RGB
和灰度图像,或者你甚至可能知道 YUV
空间。 Lab 彩色域
与之很是类似。
我对 Lab
彩色感兴趣的缘由是它对产生场景的边缘有着优异的能力。
Lab
彩色空间的每一个字母表示:
L
—— Luminance 亮度a
—— alpha —— 红到绿b
—— beta —— 黄到蓝截图13:
事实上,这些颜色通道很是适合发现颜色变化梯度,正如天然而然地黄色不多出现另外一个黄色周围,红色和绿色也是如此。(尽管我已经完全证实了)。Lab 彩色空间
与咱们人类怎样察觉颜色中的亮度有很强的相关性。与 RGB
相反的是,在 Lab 彩色域
中亮度有它本身的分离通道,这使得它能更好地处理颜色的差别,这些差别也是亮度与颜色相关之处。
为了最小化额外的代码,咱们所要作的就是把输入的图像转化为 Lab彩色域
的图像。你能够作一些最优化,不过你仅仅作了这额外的一步也能明显提升适宜的边缘检测。
% Convert an image to the Lab color space colorTransform = makecform('srgb2lab'); img = applycform(rgbImg, colorTransform); % Make it double to improve representation img = double(img); % Find x and y derivative of a 9x9 gaussian [hx, hy] = gradient(fspecial('gaussian',[9 9],sigma)); % Apply filters gx = double(imfilter(img,hx,'replicate')); gy = double(imfilter(img,hy,'replicate')); % Find absolute value gSquared = sqrt(gx .* gx) + (gy .* gy); % Apply non-maxima suppression (find best points for edges) [mag, ] = max(gSquared, [], 3);
若是咱们将 Windows XP
小山坡的背景图像转换为 Lab
,咱们将获得下面的图像:
截图14:
而后若是咱们施加滤波器(非极大值抑制)将获得下面的图像,清晰的包含着草地、云、草地和天空的分界线的图象。
Lab 彩色域
上边缘检测截图15:
最终,若是咱们运行非极大值抑制,那么咱们将获得比本文开头提到的 Canny
边缘检测器要好得多的边缘效果。
Lab 彩色域
边缘检测截图16:
平均来讲,这种方法会比普通方法提升 10%
左右的边缘检测精度。这是对 The Berkeley Segmentation Dataset and Benchmark 运行 F-measure
测试获得的结果。
截图17:
有无数的方法去作边缘检测,这里讲述的方法毫不是最好、最容易实现、最容易解释的。
我使用这些方法解释它是由于我对它们颇有兴趣。。。加上这是 UIUC《计算机视觉》 的 CS543 课程
布置的做业,因此若是你也在上这门课,请不要抄袭个人代码!
我已经把咱们全部的实现都放到了 github 上了。包括用 C++
的 OpenCV
实现。
然而,若是你想跟个人猫照相,这没什么问题。
PCA: Principal Component Analysis
Everyday Algorithms: Pancake Sort
Using Computer Vision to Improve EEG Signals
Introduction to Markov Processes The Cache and Multithreading
这是本人课余时间的翻译,若有错误,还请耐心指出,谢谢! 原文连接请点击原文连接