图像分割
一、边缘分割技术
1.图像中间断点和线段的检测
对于图像中的间断点,常用的检测模板是:[-1, -1, -1; -1, 8, -1; -1, -1, -1]
对于图像中的线段,常用的检测模板是:
水平线段 -- [-1, -1, -1; 2, 2, 2; -1, -1, -1]; +45°线段 -- [-1, -1, 2; -1, 2, -1; 2, -1, -1]
垂直线段 -- [-1, 2, -1; -1, 2, -1; -1, 2, -1]; -45°线段 -- [2, -1, -1; -1, 2, -1; -1, -1, 2]
在Matlab中,利用以上模板,通过函数imfilter() 来实现对图像中间断点和线段的检测。
% 检测图像中的线段
close all; clear all; clc;
I1 = imread('gantrycrane.png');
I = rgb2gray(I1);
figure;
subplot(121), imshow(I1);
w1 = [-1, -1, -1; -1, 8, -1; -1, -1, -1]; % 间断点检测
J1 = imfilter(I, w1);
w2 = [-1, -1, -1; 2, 2, 2; -1, -1, -1]; % 水平线段检测
J2 = imfilter(I, w2);
w3 = [-1, -1, 2; -1, 2, -1; 2, -1, -1]; % +45°线段检测
J3 = imfilter(I, w3);
w4 = [-1, 2, -1; -1, 2, -1; -1, 2, -1]; % 垂直线段检测
J4 = imfilter(I, w4);
w5 = [2, -1, -1; -1, 2, -1; -1, -1, 2]; % -45°线段检测
J5 = imfilter(I, w5);
J = J1 + J2 + J3 + J4 + J5;
subplot(122), imshow(J);
2.微分算子
常用的微分算子有sobel算子、Roberts算子和Prewitt算子等。通过这些算子,对图像进行滤波,就可以得到图像的边缘。
2.1 Roberts算子
Roberts算子由两个模板组成:[1, 0; 0, -1]和[0, 1; -1, 0]。
% 采用Roberts算子对图像进行边缘检测
close all; clear all; clc;
I = im2double(imread('rice.png'));
[J, thresh] = edge(I, 'roberts', 35/255); % 35/255表示分割阈值
figure;
subplot(121), imshow(I);
subplot(122), imshow(J);
2.2 Prewitt算子
对于复杂的图像,采用Roberts算子不能很好地得到图像的边缘,而需要采用更加复杂的3*3算子。Prewitt算子也是由两个模板组成:[-1 -1 -1; 0 0 0; 1 1 1]和[-1 0 1; -1 0 1; -1 0 1],这两个算子分别代表图像的水平梯度和垂直梯度。
% 采用Prewitt算子对图像进行边缘检测
close all; clear all; clc;
I = im2double(imread('rice.png'));
[J, thresh] = edge(I, 'prewitt', [], 'both');
figure;
subplot(121), imshow(I);
subplot(122), imshow(J);
2.3 Sobel算子
Sobel算子的大小和Prewitt算子的大小相同,都是3x3。Sobel算子也是由两个模板组成:[-1 0 1; -2 0 2; -1 0 1]和[-1 -2 -1; 0 0 0; 1 2 1]。
% 采用Sobel算子对图像进行边缘检测
close all; clear all; clc;
I = im2double(imread('rice.png'));
[J, thresh] = edge(I, 'sobel', [], 'both');
figure;
subplot(121), imshow(I);
subplot(122), imshow(J);
2.4 采用函数fspecial()产生预定义模板
在MATLAB软件中,可以通过函数fspecial()产生预定义的模板,例如h=fspecial('prewitt'),将会产生Prewitt算子水平方向上的模板,如果想得到垂直方向上的模板,对矩阵h转置即可。
% 采用函数fspecial()产生预定义模板
close all; clear all; clc;
format rat; % 设置为有理数输出
h_sobel = fspecial('sobel')
h_prewitt = fspecial('prewitt')
h_laplacian = fspecial('laplacian')
h_log = fspecial('log', 3)
format short;
在获取算子的模板之后,可以利用函数imfilter()通过模板与图像的二维卷积,来获取图像的边缘信息。
% 采用函数fspecial()和imfilter()提取图像的边缘
close all; clear all; clc;
I = im2double(imread('rice.png'));
h = fspecial('laplacian');
J = imfilter(I, h, 'replicate');
K = imbinarize(J, 30/255);
figure;
subplot(131), imshow(I);
subplot(132), imshow(J);
subplot(133), imshow(K);
3.Canny算子
Canny算子具有低误码率、高定位精度和抑制虚假边缘等优点。
% 采用Canny算子对含有噪声的图像进行边缘检测
close all; clear all; clc;
I = im2double(imread('rice.png')); % 读入图像
J = imnoise(I, 'gaussian', 0, 0.01); % 添加高斯噪声
[K, thresh] = edge(J, 'Canny'); % Canny边缘检测
figure;
subplot(131), imshow(I);
subplot(132), imshow(J);
subplot(133), imshow(K);
由图可知,Canny算子对含有噪声的图像取得了非常好的边缘提取效果。
4.LOG算子
LOG算子有很多优点,如边界定位精度高、抗干扰能力强、连续性好等。
% 采用LOG算子对含有噪声的图像进行边缘检测
close all; clear all; clc;
I = im2double(imread('rice.png'));
J = imnoise(I, 'gaussian', 0, 0.005);
[K, thresh] = edge(J, 'log', [], 2.3);
figure;
subplot(131), imshow(I);
subplot(132), imshow(J);
subplot(133), imshow(K);
二、阈值分割技术
1.全局阈值法
% 采用全局阈值对图像进行分割
close all; clear all; clc;
I = imread('rice.png');
figure;
subplot(131), imshow(I);
J = I > 120; % 设全局阈值为120
subplot(132), imshow(J);
[m, n] = size(I);
for i = 1 : m
for j = 1 : n
if ( I(i, j) > 120)
K(i, j) = 1;
else
K(i, j) = 0;
end
end
end
subplot(133), imshow(K);
% 采用函数im2bw()进行彩色图像分割
close all; clear all; clc;
[X, map] = imread('trees.tif'); % 读取索引图像
J = ind2gray(X, map); % 索引图像转换为灰度图像
K = im2bw(X, map, 0.4); % 索引图像二值化
figure;
subplot(131), imshow(X, map);
subplot(132), imshow(J);
subplot(133), imshow(K);
2.OTSU阈值分割
在MATLAB中,函数graythresh()采用otsu算法获取全局阈值,获取全局阈值后,可以采用im2bw()函数进行图像分割。
close all; clear all; clc;
I = im2double(imread('rice.png'));
level = graythresh(I); % 获取全局阈值
J = im2bw(I, level);
figure;
subplot(121), imshow(I);
subplot(122), imshow(J);
3.迭代式阈值分割
通过迭代的方法求出分割的最佳阈值,具有一定的自适应性。迭代法阈值分割的步骤是:1.设定参数T0,并选择一个初始的估计阈值T1;2.用阈值T1分割图像。将图像分成两部分:G1是由灰度值大于T1的像素组成,G2是由灰度值小于或等于T1的像素组成;3.计算G1和G2中所有像素的灰度均值μ1和μ2,以及新的阈值T2=(μ1+μ2)/2;4.如果| T2 - T1 | <T0,则退出,T2即为最优阈值,否则,将T2赋值给T1,并重复步骤2~4,知道获取最优阈值。
close all; clear all; clc;
I = imread('rice.png');
I = im2double(I);
figure;
subplot(121), imshow(I);
T0 = 0.01; % 设定参数T0
T1 = ( min(I(:)) + max(I(:))) / 2; % 初始阈值T1取图像最小值和最大值的均值
r1 = find(I > T1);
r2 = find(I <= T1);
T2 = ( mean(I(r1)) + mean(I(r2))) / 2;
while abs(T2 - T1) < T0
T1 = T2;
r1 = find(I > T1);
r2 = find(I <= T1);
T2 = ( mean(I(r1)) + mean(I(r2))) / 2;
end
J = im2bw(I, T2);
subplot(122), imshow(J);
三、区域分割技术
区域分割主要包括区域生长法和分水岭分割法。
分水岭分割相当于是一个自适应的多阈值分割算法。在MATLAB中,函数watershed()可以进行图像的分水岭分割。
% 采用分水岭算法分割图像
close all; clear all; clc;
I = imread('circbw.tif');
J = watershed(I, 8);
figure;
subplot(121), imshow(I);
subplot(122), imshow(J);
相关阅读
图像分割之(五)活动轮廓模型之Snake模型简介[email protected]://blog.csdn.net/zouxy09 在“图像分割之(一)概述”中咱们简单了解