• 图像处理之边缘检测[微分算子、Canny算子和LOG算子]


    一、边缘检测基本定义

    边缘检测是检测图像特性发生变化的位置。不同的图像灰度不同,边界处会有明显的边缘,利用此特征可以分割图像。边缘检测分割法是通过检测出不同区域边界来进行分割的。边缘总是以强度突变的形式出现,可以定义为图像局部特性的不连续性,如灰度的突变和纹理结构的突变等。图像的边缘包含了物体形状的重要信息,它不仅在分析图像时大幅度地减少了要处理的信息量,而且还保护了目标的边界结构。边缘提取和分割是图像分割的经典研究课题之一,直到现在仍然在不断改进和发展.

    常见的边缘检测方法有微分算子、Canny 算子和LOG算子等。常用的微分算子有Sobel算子、Roberts 算子和Prewit算子等。

    二、图像中的线段

    将图像点(x,y)某个邻域中每个像素值都与模板中对应的系数相乘,然后将结果进行累加,从而得到该点的新像素值。如果邻域的大小为mn,则总共有mn个系数。这些系数组成的矩阵称为模板或算子。通常采用的最小模板是3X3

    对于图像中的间断点,常用的检测模板为:
    在这里插入图片描述
    对于图像中的线段,常用的检测模板为:
    在这里插入图片描述
    这些模板分别对应的线段为水平线段、+45°线段、垂直线段和- 45°线段。在MATLAB中,可以利用模板,然后通过函数imfilter()来实现对图像中间断点和线段的检测

    实现代码:

    % 检测图像中的线段,利用模板载通过函数imfilter来实现
    close all;
    clear all;
    clc;
    I=imread('gantrycrane.png');
    I=rgb2gray(I);
    % 检测图像中的线段常用的四个模板:h1对应水平线段;h2对应+45度线段
    % h3对应垂直线段,h4对应-45度线段
    h1=[-1,-1,-1;2,2,2;-1,-1,-1];
    h2=[-1,-1,2;-1,2,-1;2,-1,-1];
    h3=[-1,2,-1;-1,2,-1;-1,2,-1];
    h4=[2,-1,-1;-1,2,-1;-1,-1,2];
    J1=imfilter(I,h1);            % 线段检测
    J2=imfilter(I,h2);
    J3=imfilter(I,h3);
    J4=imfilter(I,h4);
    J=J1+J2+J3+J4;                % 将检测到的四条线段叠加
    
    subplot(121),imshow(I);
    title('原始图像');
    subplot(122),imshow(J);
    title('检测到的线段');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    实现效果:
    在这里插入图片描述

    三、边缘检测方法

    1、微分算子

    (1)Roberts算子

    对于离散的图像f(x,y),边缘检测算子是用图像的垂直和水平差分来逼近梯度算子,即
    在这里插入图片描述
    在进行边缘检测时,对于图像中的每个像素计算梯度算子,然后求绝对值,最后进行阈值操作就可以实现。Roberts 算子的计算公式为:
    在这里插入图片描述
    Roberts算子由下面的两个模板组成:
    在这里插入图片描述
    在MATLAB软件中,采用函数edge()进行图像的边缘检测,该函数的返回值为二值图像,和输入图像大小相同,数据类型为逻辑型(logical) 。该函数可以通过Roberts算子进行边缘检测。该函数的调用格式如下:
    在这里插入图片描述

    实现代码:

    % 采用Roberts算子进行图像的边缘检测
    close all;
    clear all;
    clc;
    I=imread('rice.png');
    I=im2double(I);
    % 调用格式BW=edge(I,'roberts',thresh)采用Roberts算子对图像I进行边缘检测,thresh为分割阈值(本例中为35/255)
    % 该函数会忽略所有小于thresh的像素值,注意阈值需要进行归一化即变换到[0,1]之间
    J=edge(I,'roberts',35/255);
    
    subplot(121),imshow(I);
    title('原始图像');
    subplot(122),imshow(J);
    title('采用Roberts算子提取的边缘');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实现效果:
    在这里插入图片描述
    (2)Prewitt算子

    对于复杂的图像,采用Roberts算子不能较好地得到图像的边缘,而需要采用更加复杂的3X3的算子比如Prewitt算子。Prewitt算子的大小为3X3,其模板如下所示:
    在这里插入图片描述
    这两个算子分别代表图像的水平梯度和垂直梯度。在MATLAB中,函数edge()可以采用Prewitt算子进行边缘检测。该函数的调用格式如下:
    在这里插入图片描述
    实现代码:

    % 采用Prewitt算子进行图像的边缘检测
    close all;
    clear all;
    clc;
    I=imread('cameraman.tif');
    I=im2double(I);
    % BW=edge(I,'prewitt',thresh,direction)该函数采用Prewitt算子对图像I进行边缘检测
    % 将分割阈值thresh设置为空矩阵(即表示函数自动计算分割阈值),direction可以对方向进行设置,共有三个值:horizontal,vertical,both(默认,表示水平和垂直双方向)
    J=edge(I,'prewitt',[],'both');
    
    subplot(121),imshow(I);
    title('原始图像');
    subplot(122),imshow(J);
    title('采用Prewitt算子提取的边缘');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实现效果:
    在这里插入图片描述
    (3)Sobel算子

    Sobel算子的大小和Prewitt算子的大小相同,都是3X3。Soble算子的模板如下所示:
    在这里插入图片描述
    在MATLAB中,函数edge()可以采用Sobel算子进行边缘检测。该函数的调用格式如下:
    在这里插入图片描述
    实现代码:

    % 采用Sobel算子进行图像的边缘检测
    close all;
    clear all;
    clc;
    I=imread('gantrycrane.png');
    I=rgb2gray(I);
    I=im2double(I);
    % BW=edge(I,'sobel',thresh,direction)该函数采用Sobel算子对图像I进行边缘检测
    % 将分割阈值thresh设置为空矩阵(即表示函数自动计算分割阈值),direction可以对方向进行设置,共有三个值:horizontal,vertical,both(默认,表示水平和垂直双方向)
    J=edge(I,'sobel',[],'both');
     
    subplot(121),imshow(I);
    title('原始图像');
    subplot(122),imshow(J);
    title('采用Sobel算子提取的边缘');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    实现效果:
    在这里插入图片描述

    2、Canny算子

    Canny算子具有低误码率、高定位精度和抑制虚假边缘等优点。在MATLAB中,函数edge()可以采用Canny算子进行边缘检测。该函数的调用格式如下:
    在这里插入图片描述
    实现代码:

    % 采用Canny算子对含有噪声的图像进行边缘检测
    close all;
    clear all;
    clc;
    I=imread('rice.png');
    I=im2double(I);
    J=imnoise(I,'gaussian',0,0.01);% 添加高斯噪声
    % BW=edge(I,'canny')该函数采用Canny算子对图像I进行边缘检测
    % 并采用自动计算的低阈值和高阈值进行图像分割,函数的返回值BW为二值图像
    K=edge(J,'canny');
    
    subplot(121),imshow(J);
    title('原始图像');
    subplot(122),imshow(K);
    title('采用Canny算子提取的边缘');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    实现效果:
    在这里插入图片描述
    3、LOG算子

    拉普拉斯(Laplacian) 算子是一种不依赖于边缘方向的二阶微分算子,它是标量而不是矢量,而且具有旋转不变的性质,在图像处理中经常被用来提取图像的边缘,表达式为:
    在这里插入图片描述
    数字图像的近似公式为:
    在这里插入图片描述
    由于Laplacian算子是二阶微分算子,对图像中的噪声非常敏感。LOG算子是在经典算子的基础上发展起来的边缘检测算子,根据信噪比求得检测边缘的最优滤波器。首先采用Gaussian函数对图像进行平滑,然后采用Laplacian算子根据二阶导数过零点来检测图像边缘,称为LOG算子。LOG算子有很多的优点,如边界定位精度高,抗干扰能力强,连续性好等。在MATLAB软件中,函数edge()可以采用LOG算子进行边缘检测。该函数的调用格式如下:
    在这里插入图片描述
    实现代码:

    % 采用LOG算子对含有噪声的图像进行边缘检测
    close all;
    clear all;
    clc;
    I=imread('cameraman.tif');
    I=im2double(I);
    J=imnoise(I,'gaussian',0,0.005);% 添加高斯噪声
    % BW=edge(I,'log',thresh,sigma)该函数采用LOG算子对图像I进行边缘检测,
    % 若不设置阈值tresh或tresh为空,系统会自动计算tresh值
    % sigma为LOG滤波器的标准差默认位2
    K=edge(J,'log',[],2.3);% 采用LOG算子提取边缘
    
    subplot(121),imshow(J);
    title('原始图像');
    subplot(122),imshow(K);
    title('采用LOG算子提取的边缘');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    实现效果:

    在这里插入图片描述
    由于刚刚开始学习图像处理,对于很多知识理解不到位。如有错误,恳请指正,任重而道远,慢慢加油!

  • 相关阅读:
    10分钟,我写完了8小时的CSS样式,我真棒!
    图片操作笔记-滤波-python
    华为机试 - 约瑟夫问题
    IDEA快捷键大全
    我与世界杯足球那些事——世界杯征文
    R语言抑制代码显示警告和错误信息:suppressMessage函数和suppressuWarnings函数抑制警告信息的显示
    Centos服务在服务器重启后自启
    SQLite3 数据库学习(二):SQLite 中的 SQL 语句详解
    【递归算法】递归算法的快速入门
    用游戏来讲序列化与反序列化机制
  • 原文地址:https://blog.csdn.net/qq_44111805/article/details/126441836