形态学图像处理(原第九章)

形态学图像处理

  • 预备知识
    • 集合论中的基本概念
  • 膨胀和腐蚀
    • 膨胀
    • 结构元素的分解
    • 函数strel
    • 腐蚀
  • 膨胀与腐蚀的组合
    • 开运算和闭运算
    • 击中或击不中变换
    • 使用查找表
    • 函数bwmorph

一.预备知识

集合论中的基本概念

在数学形态语境中使用“形态学”提取图像分量,在表示和描述区域形状(如边界、骨骼、凸壳)时很有用。

集合中四种基本的状态:

或(并),与(交),非(补),差

符号分别是:

| , & , ~ ,&~

执行基本操作

>> f = Fig0903;
>> g = Fig0904;
>> subplot(231), imshow(f);
>> subplot(232), imshow(g);
>> subplot(233), imshow(f|g);
>> subplot(234), imshow(f&g);
>> subplot(235), imshow(f&~g);
>> subplot(236), imshow(~g);

image

二.膨胀和腐蚀

膨胀

膨胀是在二值图像中“加长”或“变粗”的操作。这种特殊的方式和变粗的程度由一个称为结构元素的集合控制。(实际就是将结构元素的原点与二值图像中的1重叠,将二值图像中重叠部分不是1的值变为1,完成膨胀)

结构元素基于原点的映像,就是把结构元素转180度。类似于==空间卷积==。

  • 膨胀函数

A2 = imdilate(A, B)

A和A2都是二值图像,B是指定结构元素由0和1组成的矩阵。

>> A = Fig0906;
>> B = [0 1 0; 1 1 1; 0 1 0];
>> A2 = imdilate(A, B);
>> subplot(121), imshow(A);
>> subplot(122), imshow(A2);

image

明显可以看出图片中字体的加粗。

结构元素的分解

A ⊕ B = A ⊕ (B1 ⊕ B2) = (A ⊕ B1) ⊕ B2

B膨胀A等同于B1先膨胀A,再用B2膨胀之前的结果。

image

一个行矩阵和一个列矩阵可以膨胀为一个完整的m x n 的矩阵。

函数strel

IPT函数strel可以构造各种形状和大小的结构元素。

se = strel(shape, parameters)

shape表示希望形状的字符串,parameters表示指定形状信息的参数(如大小等)。

可按照下表构造形状

image

image

>> se = strel('diamond',  5);
>> se

se = 

strel is a diamond shaped structuring element with properties:

      Neighborhood: [11×11 logical]
    Dimensionality: 2

显示出se是一个返回水平和垂直扩展+-5个像素的菱形结构元素(红线标出)

image

  • getsequence函数

decomp = getsequence(se)

用于提取并检查分解中的单个结构元素。

decomp = 

  4×1 strel array with properties:

    Neighborhood
    Dimensionality

分解后得到四个元素结构向量,可以通过索引来逐一查看。

>> decomp(1)

ans = 

strel is a arbitrary shaped structuring element with properties:

      Neighborhood: [3×3 logical]
    Dimensionality: 2
腐蚀

与膨胀相反,对二值图像中的对象进行“收缩”或“细化”。(实际上将结构元素的原点覆盖在每一个二值图像的1上,只要二值图像上有0和结构元素的1重叠,那么与原点重叠的值为0)

同样由集合与结构元素完成。

  • 腐蚀函数

IPT函数imerode执行腐蚀

A2 = imerode(A, se)

>> f = Fig0908;
>> se = strel('disk', 10);
>> g = imerode(f, se);
>> se = strel('disk', 5);
>> g1 = imerode(f, se);
>> g2 = imerode(f, strel('disk', 20));
>> subplot(221), imshow(f), title('原图');
>> subplot(222), imshow(g), title('disk 10');
>> subplot(223), imshow(g1), title('disk 5');
>> subplot(224), imshow(g2), title('disk 20');

image

要把原图中的细线去掉,要找一个足够小的结构元素来进行腐蚀处理,可以看出,在结构元素指定参数在20时细线基本都被处理掉了。

三.膨胀与腐蚀的组合

开运算和闭运算
  • 开运算

A ○ B

A被B腐蚀后,再用B膨胀腐蚀后的结果(先腐蚀再膨胀)

C = imopen(A, B)

  • 闭运算

A • B

A被B膨胀后,再用B腐蚀膨胀后的结果(先膨胀再腐蚀)

C = imclose(A, B)

A为二值图像,B为0,1矩阵组成的指定结构元素。

>> f = Fig0910;
>> se = strel('square', 40);
>> fo = imopen(f, se);
>> fc = imclose(f, se);
>> foc = imclose(fo, se);
>> subplot(221), imshow(f), title('原图');
>> subplot(222), imshow(fo), title('开');
>> subplot(223), imshow(fc), title('闭');
>> subplot(224), imshow(foc), title('开运算的闭运算');

image

在实际应用中,可以用开运算和闭运算处理指纹,以达到使图像清晰的效果。

>> f = Fig0911;
>> se = strel('square', 6);
>> fo = imopen(f, se);
>> foc = imclose(fo, se);
>> subplot(131), imshow(f), title('原图');
>> subplot(132), imshow(fo), title('开');
>> subplot(133), imshow(foc), title('开运算的闭运算');

image

开运算的闭运算可以给指纹填充缺口。

击中或击不中变换

击中击不中变换(HMT),HMT变换可以同时探测图像的内部和外部。研究解决目标图像识别和模式识别等领域,在处理目标图像和背景的关系上能够取得更好的效果。

  • 识别像素特定形状函数

C = bwhitmiss(A, B1, B2)

A表示集合,B1、B2表示结构元素

>> f = Fig0913;
>> B1 = strel([0 0 0; 0 1 1; 0 1 0]);
>> B2 = strel([1 1 1; 1 0 0; 1 0 0]);
>> C = bwhitmiss(f, B1, B2);
>> subplot(121), imshow(f), title('原图');
>> subplot(122), imshow(C), title('击中击不中变换');

image

在孤立的点或者线段的端点像素,击中或击不中变换对这类问题会有更好的处理。

使用查找表

当击中或击不中变换中的结构元素较小时,可以使用查找表计算击中击不中更快,定义一个函数endpoints处理该类问题。

  • endpoints函数
%endpoints函数
function g = endpoints(f)
persistent lut

if isempty(lut)
    lut = makelut(@endpoint_fcn, 3);
end

g = applylut(f, lut);

%endpoint_fcn函数
function  is_end_point = endpoint_fcn(nhood)

is_end_point = nhood(2, 2) & (sum(nhood(:)) == 2);

函数创建了nhoos任意形状由0和1组成的元素结构的函数句柄,并构造一个3 x 3的查找表,并将函数句柄写入。

  • 使用查找表执行击中或击不中
>> f = Fig0914;
>> g = endpoints(f);
>> subplot(121), imshow(f);
>> subplot(122), imshow(g);

image

函数bwmorph

该函数是基于膨胀、腐蚀和查找表操作的组合实现。

g = bwmorph(f, operation, n)

operation表示指定期望操作的字符串;n表示重复操作的次数(n为Inf时表示为无穷多次)。

image

>> f = Fig0917;
>> g = bwmorph(f, 'thin', 1);
>> g1 = bwmorph(f, 'thin', 3);
>> subplot(131), imshow(f), title('原图');
>> subplot(132), imshow(g), title('细化1次');
>> subplot(133), imshow(g1), title('细化3次');

image

可以明显看出细化一次和细化三次的区别,到三次细化后,一些细小的线有消失的迹象。

  • 函数bwlabel

IPT函数bwlabel用来计算二值图像中所有的连接分量。

[L, num] = bwlabel(f, conn)

L表示标记矩阵,num给出找到的连接分量总数,conn用于指定期望连接(4或8)。

  • 示例:计算和显示连接分量的质心

函数find在处理标记矩阵时很有用,可以返回某个对象所有像素的行索引和列索引。

>> [L, n] = bwlabel(f);
>> [r, c] = find(L == 3);
>> rbar = mean(r);
>> cbar = mean(c);
>> imshow(f);
>> hold on
>> for k = 1:n
[r, c] = find(L == k);
rbar = mean(r);
cbar = mean(c);
plot(cbar, rbar, 'Marker', 'o', 'MarkerEdgeColor', 'k',...
'MarkerFaceColor', 'k', 'MarkerSize', 10);
plot(cbar, rbar, 'Marker', '*', 'MarkerEdgeColor', 'w');
end

image

猜你喜欢

转载自blog.csdn.net/qq_39227338/article/details/80224509