7.边缘检测:2D运算——Canny的不同结果、单个2D边缘检测滤波器、实现边缘3种方法Matlab实战_3

目录

Canny的不同结果

单个2D边缘检测滤波器

实现边缘3种方法Matlab实战

第一种 图像差异

第二种 Canny边缘检测器

第三种 高斯拉普拉斯变换


Canny的不同结果

右边的图像是左边的一个边缘后的结果。

有趣的是,我的意思是,它看起来很不错,是一个很好的边缘图像。

但是我的第一个计算机视觉课程来自Berthold Horn,他是计算机视觉的创造者之一。

而且,他表达了他关心的是:很难知道什么时候图像的边缘的效果最好。

因为真正的问题是:你要用这些边缘来做什么?

我要说的是,Canny的边缘算子比其他边缘算子要更好。这意味着它们会把你想要的边缘拉出来,以便你将来处理。

当然,现在有一个问题,既然我们在做这些平滑的导数,那么我们用什么大小的高斯核来计算边缘呢?

正如我们之前说过的,不同的Sigmas,这里我们有Sigma 1, Sigma 2应用在这个小丑图像上,

你可以看到它对边缘图像做了什么:

大sigma检测大尺度图像,小sigma检测小尺度图像。

而选择取决于你想要做什么。

小测验:

Canny的边缘算子对噪声可能相当敏感。

A,正确,导数会加重噪声。

B,错误,梯度是用高斯算子的导数来计算的,它消除了噪声。

C,大部分是错的,这取决于你选择的。

答案:C。这与噪音规格相当不错,但你必须担心你选择的Sigma。

单个2D边缘检测滤波器

最后一件事要展示给你们的是完整的。

还记得高斯函数二阶导数的一维情况吗?

这是原来的高斯函数:

这个二阶导数是墨西哥帽算子:

当我们把它应用到 f 上时,这和平滑版的二阶导数是一样的:

我们在寻找那个点那些被称为零交叉的点,在底部的图上,它对应于边的位置:

但是在二维空间中做这个有点难,原因是:

求导的方向不止一个。

这里是高斯分布,公式是这样的,中间是一座漂亮的山:

但是我们必须在一个方向上求导,你知道的,下面这个图,这是x,这是1和Y:

在二阶导数上有三种选择。

我可以再次求x的偏导,所以 f² 的偏导是x的偏导的两倍。

我可以对y求偏导,两次。

我也可以求f关于y的偏导。

我应该用哪一个?

正确的答案是,你用的是高斯拉普拉斯方程。

拉普拉斯算子,就是x (f)对x²的二阶导数 加上 f (f)对y²的二阶导数:

这就是对称地给你这个墨西哥帽子操作符的原因:

如果你把它应用到图像上,取0叉乘,就会得到边。

实际上,如果你在matlab中运行一些关于边的演示代码。

你可以采取Canny边缘,或者取高斯分布的差异或者取高斯分布的拉普拉斯分布的差异,它们几乎是相同的。

你可以看到,它所做的是寻找0叉乘这是获得边的另一种方法。

其中一个挑战往往是封闭计数器,而Canny只能找到你那些有一定数量支持的轮廓。

我想告诉你们大多数人,更多的人可能会用canny来做常规的边缘检测。

三种方法画出边缘MATLAB实战

下面是MATLAB的一个快速演示,展示了几种不同的计算方法。

注意,你也可以用Octave来做。只需记住加载图像包。

好的,让我们读一个图像并显示它。

这里,我们使用figure打开一个新窗口,imshow显示窗口中的图像,title设置标题,所有这些都在一行中。

我们会经常使用这个习语。

>> %% Read Leaa image
>> lena = imread('Leana.png');
>> figure, imshow(lena), title('Original image , color');

代码运行如下:

现在我们将图像转换为单色或灰度。为此,我们将使用rgb2gray函数。

>> %% Read Leaa image
>> lena = imread('Leana.png');
>> figure, imshow(lena), title('Original image , color');
>>
>> %% Convert to monochrome (grayscale) using rgb2gray
>> lenaMono = rgb2gray(lens);
>> figure, imshow(lenaMono), title('Original image, monochrome');

这就是它的样子:

现在让我们创建一个平滑的图像版本。首先,使用fspecial函数创建一个高斯滤波器。

>> %% Make a blurred/smoothed version
>> h = fspecial('gaussian', [11 11], 4);
>> h

这是过滤器h的样子:

哇,把它画成一个平面可能会有帮助。

>> figure, suref(h);

代码显示:

现在将这个过滤器应用到图像上:

>> lenaSmooth = imfilter(lenaMono, h);

把这个和原来的比较一下:

第一种 图像差异

好的。对于第一种方法,我们将把图像左移一个像素,右一个像素,并计算它们的差异。

让我们复制一个平滑的版本来创建左边的图像。

为了将图像向左移动,我们复制所有像素,从第二列开始直到最后位置第一列到n - 1。

注意,这里的最后一列和第二列是相同的。

>> %% Method 1: Shift lef and right, and show diff image
>> lenaL = lenaSmooth;
>> lenaL(:, [1:(end - 1)]) = lenaL(:, [2:end]);

右边同样也是这么操作。

>> lenaR = lenaSmooth;
>> lenaR(:, [2:(end)]) = lenaR(:, [1:end - 1]);

现在我们计算两张图片的差异,记住转换为double类型。

注意,差异可能包含负数。

>> lenaDiff = double(lenaR) - double(lenaL);

为了正确显示它,我们传入一个空向量作为第二个参数。

>> figure, imshow(lenaDiff, []), title('Difference between right and left shifted images');

代码显示:

请注意,对象边界是如何被突出显示为较亮或较暗的区域的,这表示更大的正或负差异。

其他区域几乎是灰色的,表明接近于零的差异。

第二种 Canny边缘检测器

第二种方法是使用canny边缘检测器。

我们使用edge函数,传入'canny'作为方法参数。

>> %% Method 2: Canny edge detector
>> cannyEdges = edge(lenaMono, 'canny');
>> figure, imshow(cannyEdges), title('Edges of smoothed image');

代码结果:

还记得Canny算法执行非极大抑制吗?

这与其他一些技巧一起,产生了更有意义的边缘图像:

我们还可以在平滑的图像上运行Canny边缘检测器:

注意,现在有很多细节特性都消失了。

这是原始的边缘集,以供比较:

第三种 高斯拉普拉斯变换

我们的最后一种方法使用高斯拉普拉斯算子。

继续使用edge函数,您只需要将'log'作为方法参数传入。

%% Method 3: Laplacian of Gaussian
>> logEdges = edge(lenaMono, 'log');
>> figure, imshow(logEdges), title('Laplacian of Gaussian');

同样,Canny所发现的边缘被显示出来进行比较:

您可以使用doc edge找到更多可用的选项。

>> doc edge

代码运行结果:

如您所见,您还可以应用其他的边缘运算符,以及传入定制参数。

结语:

这就是关于边缘检测的环节的总结,事实上,目前都是关于图像处理的。

希望你们已经学了一些卷积和相关滤波的知识,以及求导的概念。

我们还讨论了过滤器被用作模板。接下来,我们要做的是我们要绕一圈,做一些真正的电脑视觉。

也就是说,计算一些数据结构告诉我们从图像中得到了什么,我们会使用这些边然后我们会回来做更多关于图像处理的事情。

但是首先,你必须要去找一些线条,圆圈,硬币和图片里的东西。非常酷。


——学会编写自己的代码,才能练出真功夫。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值