【计算机视觉】图像分割与特征提取——基于Log、Canny的边缘检测_log图像分割模板

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

8420b26844034fab91b6df661ae68671.png

个人简介 

> 📦个人主页赵四司机
> 🏆学习方向JAVA后端开发 
> ⏰往期文章SpringBoot项目整合微信支付
> 🔔博主推荐网站牛客网 刷题|面试|找工作神器
> 📣种一棵树最好的时间是十年前其次是现在
> 💖喜欢的话麻烦点点关注喔你们的支持是我的最大动力。

前言

实验中要求能够自行评价Log、Canny算子在无噪声条件下和噪声条件下的分割性能。能够掌握分割条件(阈值等)的选择。完成规定图像的处理并要求正确评价处理结果能够从理论上作出合理的解释。通过实验体会一些主要的分割算子对图像处理的效果以及各种因素对分割效果的影响。

目录

一相关概念

1.一阶导数二阶导数在图像边缘中的应用 

2.边缘检测基本步骤

3.好的边缘检测遵循的原则

4.二阶微分差分算子

二拉普拉斯算子

1.等效式

2.拉普拉斯算子

​​​​3.拉普拉斯算子缺点 

三高斯-拉普拉斯算子Log

1.相关概念

2.Log边缘检测

1基本特征

2 代码实战

3结果分析

四Canny边缘检测

1.相概念

2.检测步骤

3.代码实战

4.结果分析 

五思考总结


一相关概念

1.一阶导数二阶导数在图像边缘中的应用 

  • 一阶导数可以用于检测图像中的一个点是否是边缘点判断一个点是否在斜坡上
  • 二阶导数可以用于判断一个边缘像素是在边缘亮的一边还是暗的一边。 

2.边缘检测基本步骤

  1. 滤波边缘检测算法主要是基于图像强度的一阶和二阶导数但导数的计算对噪声很敏感因此必须使用滤波器来改善与噪声有关的边缘检测器的性能.需要指出大多数滤波器在降低噪声的同时也导致了边缘强度的损失因此增强边缘和降低噪声之间需要折衷。
  2. 增强增强边缘的基础是确定图像各点邻域强度的变化值.增强算法可以将邻域或局部强度值有显著变化的点突显出来.边缘增强一般是通过计算梯度幅值来完成的。
  3. 检测在图像中有许多点的梯度幅值比较大而这些点在特定的应用领域中并不都是边缘所以应该用某种方法来确定哪些点是边缘点.最简单的边缘检测判据是梯度幅值阈值判据。
  4. 定位如果某一应用场合要求确定边缘位置则边缘的位置可在子像素分辨率上来估计边缘的方位也可以被估计出来 

3.好的边缘检测遵循的原则

  • 有好的检测率

    •  最优的检测器应该能检测出所有真实边缘而忽略噪声和其他瑕疵

  • 有好的局部化效果

    •  检测到的边缘必须尽可能的靠近真实边缘

    • 对于每个真实边缘点检测器必须返回一个点

4.二阶微分差分算子

        如果所求的一阶导数高于某一阈值则确定该点为边缘点这样做会导致检测的边缘点太多。 一种更好的方法就是求梯度局部最大值对应的点并认定它们是边缘点通过去除一阶导数中的非局部最大值可以检测出更精确的边缘。 一阶导数的局部最大值对应着二阶导数的零交叉点。这样通过找图像强度的二阶导数的零交叉点就能找到边缘点。

二拉普拉斯算子

1.等效式

   

2.拉普拉斯算子

    

  • 二阶微分关心的是图像灰度的突变而不强调灰度缓慢变化的区域对边缘的定位能力更强。
  •  Laplace算子是各项同性的即具有旋转不变性

​​​​3.拉普拉斯算子缺点 

  • 拉普拉斯的二阶方向导数算子在机器视觉中并不常用 因为任何包含有二阶导数的算子比只包含有一阶导数的算子更易受噪声的影响.甚至一阶导数很小的局部峰值也能导致二阶导数过零点.
  • 为了避免噪声的影响必须采用特别有效的滤波方法.
  • 边缘的方向信息丢失。

三高斯-拉普拉斯算子Log

1.相关概念

        Marr和Hildreth将高斯滤波和拉普拉斯边缘检测结合在一起首先用高斯函数先进行低通滤波然后利用拉普拉斯算子进行高通滤波并提取零交叉点形成LoGLaplacian of Gaussian算法也称之为拉普拉斯高斯算法. 

  

2.Log边缘检测

1基本特征

  • 平滑滤波器是高斯滤波器.
  • 采用拉普拉斯算子计算二阶导数.
  • 边缘检测判据是二阶导数零交叉点并对应一阶导数的较大峰值.
  • 使用线性内插方法在子像素分辨率水平上估计边缘的位置.  
  • 为什么使用高斯滤波器
    • 逼近必须能够抑制噪声效应
    • 必须尽量精确地确定边缘的位置  
    • 但平滑去噪和边缘检测是一对矛盾抑制噪声和边缘精确定位是无法同时得到满足的。应用高斯函数的一阶导数在二者之间获得最佳的平衡。

2 代码实战

对图像加入不同噪声之后使用Log算子进行边缘检测

I = rgb2gray(imread('image\room.tif'));
J=imnoise(f,'gaussian',0.1);

BW1 = edge(I,'log',0.004); % σ=2
BW2 = edge(J,'log',0.012,2); % σ=2
figure(1),subplot(121),imshow(J),title('gaussian = 0.1');
subplot(122),imshow(BW2);title('THRESH = 0.012 σ=2');
imshow(BW1);title('σ=2')

BW1 = edge(I,'log',0.004,3); % σ=3

figure, imshow(BW1);title('σ=3')

  

图3.4-1 Log算子Sigma = 2

  

图3.4-2 Log算子Sigma = 3

  

图3.4-3 Log算子加入高斯0噪声Sigma=2

  

图3.4-4 Log算子加入强度0.1高斯噪声THRESH=0.01Sigma=2

  

图3.4-5 Log算子加入强度0.1高斯噪声THRESH=0.012Sigma=2

3结果分析

        Log算子我采用了matlab自带的函数进行实验edge(I,'log',THRESH,SIGMA)

可以看到有两个参数THRESH表示函数忽略所有强度不大于THRESH值的边缘SIGMA作为LoG过滤器的标准差。

        LoG算子将高斯滤波和拉普拉斯边缘检测结合在一起首先用高斯函数先进行低通滤波然后利用拉普拉斯算子进行高通滤波并提取零交叉点。可以看到处理结果的图像边缘较平滑见图3.4-1是因为LoG算子不能检测边缘方向。而且在加入噪声之后可以看到LoG算子对噪声十分敏感见图3.4-3不断调整参数最终在参数THRESH=0.012Sigma=2时得到较好的结果见图3.4-5但是还是损失了很多边缘信息。

四Canny边缘检测

1.相概念

        Canny边缘检测是一种非常流行的边缘检测算法计算机视觉中用得最广的边缘检测器是John Canny在1986年提出的(发表在PAMI)。

        理论模型加性噪声干扰的阶梯边缘Step-Edge Canny展示了高斯函数的一阶导紧密逼近最优化信噪比和局部化的边缘算子 

2.检测步骤

步骤1. 图像与高斯平滑滤波器卷积

步2. 使用一阶有限差分计算偏导数阵列PQ

步骤3.  计算梯度幅值与方向角:

步骤4. 非极大值抑制NMS

    去掉幅值局部变化非极大的点.

    * 将梯度角离散为圆周的四个扇区之一以便用3×3的窗口作抑制运算

   * 方向角离散化

    

   * 抑制得到新幅值图

  

步骤5. 阈值化

取高低两个阈值作用于幅值图N[i,j]得到两个边缘图高阈值和低阈值边缘图。连接高阈值边缘图出现断点时在低阈值边缘图中的8邻点域搜寻边缘点。

3.代码实战

% I = rgb2gray(imread('image\room.tif'));
% J=imnoise(I,'gaussian',0);
% BW1 = edge(I,'canny',0.1);
% BW2 = edge(J,'canny',0.175,1.9);
% figure(2),subplot(121),imshow(J),title('加入gaussian噪声原图');
% figure(2),subplot(122),imshow(BW2),title('加入gaussian噪声后检测结果');
% figure(1),subplot(121),imshow(I),title('原图');
% subplot(122),imshow(BW1);title('自带函数Canny边缘检测');



% 自编程实现canny算子
% image = rgb2gray(imread('image\lena.png'));
% image=imnoise(image,'gaussian',0);
image = imread('image\figure.png');
image = rgb2gray(image);
subplot(221);
imshow(image);
title('原始图像');
image = double(image)/256;
[m,n] = size(image);
w = fspecial('gaussian');
image_1 = imfilter(image,w,'replicate');
subplot(222);
imshow(int8(256*image_1));
title('高斯滤波后的图像');

% 梯度计算
op = fspecial('sobel')/4;  % 用Sobel算子来求导数
x = op';
y =op;
bx = imfilter(image_1,x,'replicate');
by = imfilter(image_1,y,'replicate');
b_abs = sqrt(bx.*bx+by.*by);        % 求梯度的幅值
b_angle = angle(by-1i*bx);
b_ang = b_angle/3.1416*180;         % 求梯度的方向

% 梯度方向确定
dir=ones(m,n);
for r = 1:m
    for c = 1:n
        if((b_ang(r,c)>=22.5 && b_ang(r,c)<67.5)|| (b_ang(r,c)>=-157.5 && b_ang(r,c)<-112.5))
            dir(r,c) = 1;
        elseif ((b_ang(r,c)>=67.5 && b_ang(r,c)<112.5)|| (b_ang(r,c)>=-112.5 && b_ang(r,c)<-67.5))
            dir(r,c) = 2;
         elseif ((b_ang(r,c)>=112.5 && b_ang(r,c)<157.5)|| (b_ang(r,c)>=-67.5 && b_ang(r,c)<-22.5))
            dir(r,c) = 3;
        else
            dir(r,c) = 0;
        end
    end
end

% 遍历图像(抑制非极大值)
b_ab = [zeros(m,1),b_abs,zeros(m,1)];    % 串联矩阵
b_ab = [zeros(1,n+2);b_ab;zeros(1,n+2)];
b1=ones(m,n);
for r = 2:m+1
    for c = 2:n+1
        switch dir(r-1,c-1)
            case 0
                if((b_ab(r,c)<b_ab(r+1,c))|| (b_ab(r,c)<b_ab(r-1,c)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 1
                if((b_ab(r,c)<b_ab(r+1,c-1))|| (b_ab(r,c)<b_ab(r-1,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 2
                if((b_ab(r,c)<b_ab(r,c-1))|| (b_ab(r,c)<b_ab(r,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
            case 3
                if((b_ab(r,c)<b_ab(r-1,c-1))|| (b_ab(r,c)<b_ab(r+1,c+1)))
                    b1(r-1,c-1) = 0;
                else
                    b1(r-1,c-1) = b_ab(r,c);
                end
        end
    end
end

% 高阈值保留
b2=ones(m,n);
for r = 1:m
    for c = 1:n
        if (b1(r,c)>0.5)
            b2(r,c) = 0;
        else
            b2(r,c) = 1;
        end
    end
end

% 低阈值舍弃
b3=ones(m,n);
for r = 1:m
    for c = 1:n
        if(b1(r,c)<0.08)
            b3(r,c) = 1;
        else
            b3(r,c) = 0;
        end
    end
end

% 介于高低阈值之间
image_2 = b2;
for r = 2:m-1
    for c = 2: n-1
        if (image_2(r,c)== 1 && (b3(r,c)==0||b3(r+1,c)==0 ...
            ||b3(r+1,c-1)==0||b3(r+1,c+1)==0||b3(r,c-1)==0 ...
            ||b3(r,c+1)==0||b3(r-1,c-1)==0||b3(r-1,c)==0 ...
            ||b3(r-1,c+1)==0))
            image_2(r,c) = 0;
        else
            image_2(r,c) = 1;
        end
    end
end

%去除黑边
image_2(1,:) = 1;
image_2(m,:) = 1; 
image_2(:,1) = 1;
image_2(:,n) = 1;

subplot(223);
imshow(image_2);
title('Canny算子检测后的图像');

4.结果分析 

  

图3.5-1 Matlab自带canny函数检测结果

图3.5-2 Matlab自带canny函数检测加入高斯噪声图像结果 

图3.5-3 自编程实现canny算子检测结果

  

图3.5-4 自编程实现canny算子检测加入高斯噪声图像结果

        Canny算子能够有效地抑制噪声且其根据信噪比与定位比乘积进行测度得到最优化逼近算子能较精确确定边缘的位置。类似于LoG边缘检测方法Canny也属于先求平滑后求导数的方法。Canny边缘检测算法可以简化为四个步骤

步骤1用高斯滤波器平滑处理原图像
步骤2用一阶偏导的有限差分进行计算梯度的幅值和方向
步骤3对梯度幅值进行非极大值抑制
步骤4用双阈值算法检测和连接边缘

        使用平滑滤波的原因从根本上来说是边缘检测算子中的导数计算。导数计算对噪声十分敏感如果不提前使用滤波器加以改善则在导数计算后噪声将会被放大使得检测出来的虚假边缘变多不利于边缘的提取。但是平滑滤波虽然能有效抑制噪声但是会使得图像边缘模糊增加了边缘检测的不确定性但是噪声带来的影响更大因此首先应考虑去除噪声。图像的边缘有方向和幅度两个属性沿边缘方向像素变化平缓垂直于边缘方向像素变化剧烈边缘上的这种变化可以用微分算子检测出来通常用一阶或二阶导数来检测边缘。在这里选用一阶导数来检测边缘即求一阶导数最大值。设M(x,y)代表幅值当其取得局部最大值时其对应的梯度方向θ(x,y)反映了边缘的方向边缘方向与梯度方向垂直。得到全局梯度之后还不能确定边缘还需要保留局部梯度最大的点且还要抑制非极大值即将非局部最大值的像素点置为0。这就需要利用梯度的方向与领域像素的梯度幅值进行比较在程序中我采用的是3*3的窗口做抑制运算对每个像素点与沿着梯度方向的两个八领域像素的梯度进行比较最后选取梯度值最大的点。这样就基本排除了非边缘信息仅仅保留了一些细的线条即候选边缘。最后还需要采用双阈值法来检测和连接边缘将高于高阈值的像素点保留将低于低阈值的像素点排除若高阈值图像边缘出现0值像素点则判断该像素点低阈值图像8领域空间的像素是否存在高于高阈值的像素如果存在则该像素被保留像素值置为1否则被排除至此就实现了Canny边缘检测。

        从实验结果见图3.5-3来看Canny算子检测出来的边缘信息更准确显示出来的边缘线条较细。且在加入噪声之后由于前面利用平滑滤波过滤了噪声最后得到的边缘检测结果也还是较满意的见图3.5-4但是由于原图像有些边缘周围的像素值较小且变化较平缓例如屋顶区域在进行平滑滤波时容易将边缘信息抹除故最终检测结果屋顶部分的边缘便消失了。

五思考总结

1评价一下Roberts 算子、Prewitt 算子、Sobel 算子对于噪声条件下边界检测的性能。

        从上面的检测结果来看Roberts算子采用的是2*2的模板对噪声比较敏感对有噪声的图像处理能力不强而Prewitt算子采用的是3*3的模板其抗噪能力要强一些但是效果也不是很理想对于Sobel算子其在Prewitt算子升增加了权重的概念具有平滑噪声的作用因此其对有噪声图像的边缘检测能力要比另外两个算子强。

2为什么LoG梯度检测算子的处理结果不需要象Prewitt 等算子那样进行幅度组合

        因为LoG算子采用拉普拉斯算子计算二阶导数且边缘检测判据是二阶导数零交叉点并对应一阶导数的较大峰值还使用线性内插方法在子像素分辨率水平上估计边缘的位置。

3实验中所使用的四种算子所得到的边界有什么异同

        Roberts、Prewitt、Sobel算子得到的边缘信息较粗定位都不是很准确而LoG算子得到的边缘信息定位较准确且得到的边缘线条较细。对于有噪声的图像Roberts、Prewitt、LoG算子都对噪声比较敏感处理能力一般而Sobel算子能对噪声进行平滑其对噪声图片的边缘检测要比另外三个好。

4比较边缘提取中LOG、Canny算子的边缘提取效果。

        相同尺度下的LOG算子总是能比Canny算子检测出更多的细节Canny算子能对真正比较显著地边缘给出检测。LOG算子容易受尺度的影响不同尺度下的边缘点要用不同尺度的LOG算子检测Canny 算子受尺度的影响不太明显不同尺度下边缘点的位置都有偏差但几乎相同从对噪声的敏感程度来看LOG边缘检测子是采用二阶导数过零点的检测方法故对噪声更敏感一些因此从抑制噪声方面来讲Canny边缘检测子不容易受到噪声的干扰而相同尺度下LOG算子却容易受到噪声的干扰抑制噪声的能力要弱一些。LOG算子对噪声的抑制能力随着尺度的增加而增加相同尺度下的Canny算子比LOG算子的抗噪声能力强而LOG算子比Canny算子的边缘点准确对于弱边缘由于Canny边缘检测子采用两种不同的阈值分别检测强边缘和弱边缘并且当弱边缘和强边缘相连时才将弱边缘包含在输出图像中故而Canny算子更能检测出真正的弱边缘但是Canny边缘检测子检测出的边缘的位置会有一定范围的误差对于假边缘LOG边缘检测子相对比较容易受到噪声干扰会检测出更多的细节也容易检测出一些由于噪声引起的假边缘但是LOG边缘检测子对边缘位置的检测还是很准确的。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6