1 原理
1.1 边缘检测概述
边缘检测是图像处理和计算机视觉中的基本问题,其目的在于标识数字图像中亮度变化明显的点。这些变化通常反映了图像属性的重要事件和变化,如深度不连续、表面方向不连续、物质属性变化和场景照明变化等。边缘检测在特征提取中起着关键作用,因为它能够大幅度地减少数据量,并剔除不相关的信息,同时保留图像重要的结构属性。
1.2 Prewitt算子
Prewitt算子是一种一阶微分算子的边缘检测。它利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。
公式表示:
对于数字图像f(x,y),Prewitt算子的定义如下:
G(i) = | [f(i-1,j-1) + f(i-1,j) + f(i-1,j+1)] - [f(i+1,j-1) + f(i+1,j) + f(i+1,j+1)] |
G(j) = | [f(i-1,j+1) + f(i,j+1) + f(i+1,j+1)] - [f(i-1,j-1) + f(i,j-1) + f(i+1,j-1)] |
1.3 Roberts算子
Roberts算子由Lawrence Roberts在1963年提出,基于离散微分的原理,通过计算图像上相邻像素点之间的差异来检测边缘。它使用两个2x2的模板进行卷积操作。
模板表示:
Gx = [[1, 0], [0, -1]]
Gy = [[0, 1], [-1, 0]]
1.4 Sobel算子
Sobel算子是一种一阶导数的边缘检测算子,在算法实现过程中,通过3×3模板作为核与图像中的每个像素点做卷积和运算,然后选取合适的阈值以提取边缘。
公式表示:
Sx = (Z1 + 2Z2 + Z3) - (Z7 + 2Z8 + Z9)
Sy = (Z1 + 2Z4 + Z7) - (Z3 + 2Z6 + Z9)
1.5 LoG(Laplacian of Gaussian)算子
LoG算子结合了高斯平滑和拉普拉斯算子。首先使用高斯滤波器对图像进行平滑处理,然后利用拉普拉斯算子进行边缘检测。这样可以减少噪声对边缘检测的影响。
高斯平滑公式(见参考文章7的高斯滤波公式)
LoG算子公式(见参考文章6的LoG函数表达式)
1.6 Canny边缘检测算法
Canny边缘检测算法是一个多级检测算法,结合了高斯滤波、梯度的强度和方向、双阈值处理和边缘跟踪等技术。其目标是找到一个最优的边缘检测算法。
由于Canny边缘检测算法涉及多个步骤和复杂的计算,其完整的公式和算法流程较为复杂,无法在此处直接给出。但基本思想是利用高斯滤波平滑图像,计算梯度的强度和方向,然后通过双阈值处理和边缘跟踪来确定边缘。
以上即为边缘检测及其常见算子的简要介绍和原理公式。在实际应用中,可以根据具体需求和图像特性选择合适的边缘检测算法。
2 代码
Matlab
%% 清空环境变量
warning off % 关闭报警信息
close all % 关闭开启的图窗
clear % 清空变量
clc % 清空命令行
%% 图像预处理-高斯滤波与图像去噪
I = imread('test.jpeg');
if size(I, 3) == 3
% 如果是彩色图像,转换为灰度图像
I = rgb2gray(I);
end
I = im2double(I); % 将图像转换为双精度,范围在[0, 1]
% 对图像进行高斯滤波
h = fspecial('gaussian', [5 5], 1); % 创建一个5x5的高斯滤波器,标准差为1
I_gaussian = imfilter(I, h);
% 绘制原始图像和原始直方图
figure;
subplot(3, 2, 1),imshow(I);
title('原始图像');
subplot(3, 2, 2),imhist(I);
title('原始直方图');
% 绘制高斯滤波后的图像和对应的直方图
subplot(3, 2, 3),imshow(I_gaussian);
title('高斯滤波后的图像');
subplot(3, 2, 4),imhist(I_gaussian);
title('高斯滤波后的直方图');
% 去噪使用中值滤波
I_denoised = medfilt2(I); % 使用中值滤波进行去噪
% 绘制去噪后的图像和对应的直方图
subplot(3, 2, 5),imshow(I_denoised);
title('去噪后的图像');
subplot(3, 2, 6),imhist(I_denoised);
title('去噪后的直方图');
%% %% 边缘检测
% 读取图像
I6 = imread('test.jpeg');
I6 = rgb2gray(I6); % 转换为灰度图像
% 初始化figure和subplot
figure;
% 绘制原始图像作为对比
subplot(3, 2, 1);
imshow(I6);
title('原始图像');
% Prewitt边缘检测
BW_prewitt = edge(I6, 'prewitt');
subplot(3, 2, 2);
imshow(BW_prewitt);
title('Prewitt 边缘检测');
% Roberts边缘检测
BW_roberts = edge(I6, 'roberts');
subplot(3, 2, 3);
imshow(BW_roberts);
title('Roberts 边缘检测');
% Sobel边缘检测
BW_sobel = edge(I6, 'sobel');
subplot(3, 2, 4);
imshow(BW_sobel);
title('Sobel 边缘检测');
% LoG边缘检测
BW_log = edge(I6, 'log');
subplot(3, 2, 5);
imshow(BW_log);
title('LoG 边缘检测');
% Canny边缘检测(需要设置阈值)
BW_canny = edge(I6, 'canny', [0.4, 0.7]); % 这里设置了高低两个阈值
subplot(3, 2, 6);
imshow(BW_canny);
title('Canny 边缘检测');
% 添加标签和标题
set(gcf, 'Name', '边缘检测算子比较');
%% 图像预处理-灰度化与图像反白
I1 = imread('test.jpeg');
figure;
subplot(2,2,1);%用subplot建立多个子图
imshow(I1);%用imshow显示图像I
title('原始彩色图像');
J=rgb2gray(I1);%将彩色图像工转换为灰度图像J
subplot(2,2,2);imshow(J);% 用imshow显示图像J
title('灰度图像');
subplot(2,2,3);imhist(J);% 计算和显示灰度图像J的灰度直方图
title('灰度直方图');
Ave = mean2(J);%用mean2函数求图像J的均值
SD = std2(double(J));%用std2函数求图像J的均值
s= size(J);%图像大小为s(1)×s(2)
all_white = 255*ones(s(1),s(2));%设置全部为白色灰度255
all_white_uint8=uint8(all_white);%将double类型矩阵转化为uint8类型矩阵
K= imsubtract(all_white_uint8,J);%图像相减得反白图像K
subplot(2,2,4);imshow(K);%用imshow显示图像K
title('反白图像');
%% 线性变换进行图像增强
I2= imread('test.jpeg');
J2=rgb2gray(I2);
figure;
subplot(2,2,1), imshow(J2) ;
title('原始图像');
subplot(2,2,2), imhist(J2) ;%显示原始图像的直方图
title('原始灰度直方图');
K = imadjust(J2,[0.4 0.6],[]);%使用imadjust函数进行灰度的线性变换
subplot(2,2,3), imshow(K);
title('线性变换后的灰度图像');
subplot(2,2,4),imhist(K)%显示变换后图像的直方图
title('线性变换后的灰度直方图');
%% 伽马变换进行图像增强
figure;
subplot(3,2,1), imshow(J2) ;
title('原始图像');
subplot(3,2,2), imhist(J2) ;%显示原始图像的直方图
title('原始灰度直方图');
gamma = 0.5;
I_gamma = imadjust(J2, [], [], gamma);
subplot(3,2,3),imshow(I_gamma);
title('伽马变换后的灰度图像');
subplot(3,2,4),imhist(I_gamma);
title('伽马变换后的灰度直方图');
%% % 对数变换进行图像增强
c = 0.5; % 控制参数,用于避免log(0)
I_log = c * log(1 + double(J2)) / log(256);
I_log = im2uint8(I_log);
subplot(3,2,5);
imshow(I_log);
title('对数变换后的图像');
subplot(3,2,6);
imhist(I_log);
title('对数变换后的灰度直方图');
%%
figure('Position',[50 50 800 600])
subplot(4,2,1), imshow(J2);
title('原始图像');
subplot(4,2,2), imhist(J2);
title('原始灰度直方图');
subplot(4,2,3), imshow(K);
title('线性变换后的灰度图像');
subplot(4,2,4),imhist(K)%显示变换后图像的直方图
title('线性变换后的灰度直方图');
subplot(4,2,5),imshow(I_gamma);
title('伽马变换后的灰度图像');
subplot(4,2,6),imhist(I_gamma);
title('伽马变换后的灰度直方图');
subplot(4,2,7),imshow(I_log);
title('对数变换后的图像');
subplot(4,2,8),imhist(I_log);
title('对数变换后的灰度直方图');
%% 直方图均衡化进行图像增强
I3 = imread('test.jpeg'); % 读取图像
I_gray = rgb2gray(I3); % 转换为灰度图像
% 直方图均衡化
I_eq = histeq(I_gray);
% 显示原始图像和增强后的图像
figure;
subplot(2, 2, 1),imshow(I_gray);
title('原始图像');
subplot(2, 2, 2);
imhist(I_gray),title('原始灰度直方图');
subplot(2, 2, 3),imshow(I_eq);
title('直方图均衡化后的图像');
subplot(2, 2, 4),imhist(I_eq);
title('直方图均衡化后的灰度直方图');