Sobel 算子法
1、 Sobel 算子
采用梯度微分锐化图像,同时会使噪声、条纹等得到增强, Sobel 算子则在一定程度上克服了这个问题。
Sobel 算子的基本原理:定义 Sobel 算子滤波器,对图像施加空间滤波,将滤波结果作为变换后图像 f(i,j) 的灰度。
Sobel 算子滤波器分垂直、水平滤波器两种:
Sobel 算子不像普通梯度算子那样用两个像素的差值、从而有以下两个优点:
(1)由于引入了平均因素,因而对图像中的随机噪声有一定的平滑作用。
(2)由于它是相隔两行或两列之差分,故边缘两侧元素得到了增强,边缘显得粗而亮。
2、代码实现
计算梯度模 G , G^2 = Gx^2+Gy^2 ,简化为求 |G| = |Gx|+|Gy|
计算 Gx = [f(x+1,y-1) + 2*f(x+1,y) + f(x+1,y+1)]-[f(x-1,y-1) + 2*f(x-1,y) + f(x-1,y+1)]
计算 Gy = [f(x-1,y-1) + 2*f(x,y-1) + f(x+1,y-1)]-[f(x-1,y+1) + 2*f(x,y+1) + f(x+1,y+1)]
%% 锐化空间滤波器 Sobel 算子
% 作者:杨宇东
% 日期:2014.09.28
% 参数:待均衡化的图片的文件名
% 输出:均衡化处理之后的图片数组
%%
function g = EdgeDetectionSobel(imgFile)
% Sobel 算子
sobelOperator = [1, 2, 1; 2, 2, 2;1, 2, 1];
threshold = 100;
im = imread(imgFile);
[nHeight, nWidth, nDim] = size(im);
if nDim == 3
img = rgb2gray(im);
end
% 将图像放在一个增加了一个像素边框的新图像中
f = zeros(nHeight + 2, nWidth + 2);
f(2:nHeight + 1, 2:nWidth + 1) = img;
f(2:nHeight + 1, 1) = img(1:nHeight, 1);
f(2:nHeight + 1, nWidth + 2) = img(1:nHeight, nWidth);
f(1, 2:nWidth + 1) = img(1, 1:nWidth);
f(nHeight + 2, 2:nWidth + 1) = img(nHeight, 1:nWidth);
f(1, 1) = img(1, 1);
f(1, nWidth + 2) = img(1, nWidth);
f(nHeight + 2, 1) = img(nHeight, 1);
f(nHeight + 2, nWidth + 2) = img(nHeight, nWidth);
g = zeros(nHeight, nWidth);
for i = 2:nHeight + 1
for j = 2:nWidth + 1
subMat = zeros(3, 3);
subMat(:, :) = f(i-1:i+1,j-1:j+1);
% 计算 Gx 、 Gy
for x = 1:3
for y = 1:3
subMat(x, y) = subMat(x, y) * sobelOperator(x, y);
end
end
% 计算 Gx = [f(x+1,y-1) + 2*f(x+1,y) + f(x+1,y+1)]-[f(x-1,y-1) + 2*f(x-1,y) + f(x-1,y+1)]
% 计算 Gy = [f(x-1,y-1) + 2*f(x,y-1) + f(x+1,y-1)]-[f(x-1,y+1) + 2*f(x,y+1) + f(x+1,y+1)]
% 简化为 |G| = |Gx| + |Gy|
% of = ((subMat(3, 1) + subMat(3, 2) + subMat(3, 3)) - (subMat(1, 1) + subMat(1, 2) + subMat(1, 3)))^2 + ((subMat(1, 3) + subMat(2, 3) + subMat(3, 3)) - (subMat(1, 1) + subMat(2, 1) + subMat(3, 1)))^2;
% of = sqrt(of);
of = abs((subMat(3, 1) + subMat(3, 2) + subMat(3, 3)) - (subMat(1, 1) + subMat(1, 2) + subMat(1, 3))) + abs((subMat(1, 3) + subMat(2, 3) + subMat(3, 3)) - (subMat(1, 1) + subMat(2, 1) + subMat(3, 1)));
if of > threshold
g(i, j) = 0;
else
g(i, j) = 255;
end
end
end
subplot(2, 1, 1),imshow(im);
subplot(2, 1, 2),imshow(g);
调用 Matlab 自带的 edge 函数也可以实现,而且经过测试,自带的函数比自己所写的函数效率高了10倍左右。
%% 锐化空间滤波器 Sobel 算子 调用系统函数解决
% 作者:杨宇东
% 日期:2014.09.28
% 参数:待均衡化的图片的文件名
% 输出:f 均衡化处理之后的图片数组; t 系统给出的阈值
%%
function [f, t] = MatLabSobel(imgFile)
im = imread(imgFile);
img = rgb2gray(im);
% 在垂直方向上使用 matlab 的边界检测函数,调用的算子是 Sobel 算子,阈值由系统自定
[f, t] = edge(img, 'sobel', 'vertical');
subplot(2, 1, 1),imshow(im);
subplot(2, 1, 2),imshow(f);