【matlab代码练习15】图像分割技术

一、边缘分割技术

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); 

猜你喜欢

转载自blog.csdn.net/qq_15971883/article/details/80259317