MATLAB学习笔记 表示与描述

表示与描述

表示区域涉及到二个基本选择:
* 用外部特征(区域的边境)表示区域
* 用内部特征(组成区域的像素)表示区域
描述就是你在表示区域的基础上进行的,例如区域可以用边界表示,而边界可以用诸如边界长度和其包含的凹面形状的数目等特征来描述。

单元数组与结构
单元数组

就是cell

a = [1 2 3];
c = {'asd', a, 12};
disp(c); % 输出'asd'    [1x3 double]    [12]

使用的话就用{}来表示下标

a = [1 2 3];
c = {'asd', a, 12};
disp(c{2}); % 输出 1 2 3
disp(c{2}(2)); % 输出 2

用()可以获得单元数组元素的信息(基本元素则直接输出)

a = [1 2 3];
c = {'asd', a, 12};
c(1) % 输出 'asd'
c(2) % 输出 [1x3 double]

同样适用于size函数!

celldisp 递归输出单元数组的信息(就是会输出单元数组里的元素数据而不是元素信息)

a = [1 2 3];
c = {'asd', a, 12};
celldisp(c); % 输出 c{1} = asd c{2} = 1 2 3 c{3} = 12
disp(c); % 输出'asd' [1x3 double] [12]

cellfun(@fun, C) 可以将C 的元素依次调用fun(C), gen celldisp差不多

a = [1 2 3];
c = {'asd', a, 12};
[r c] = cellfun(@size, c);
r, c % 输出 r = 1 1 1 c = 3 3 1
结构

类似于高级语言的结构体(类)
调用方法也也差不多。

s.a = 1;
s.b = 2;
s % 输出s = a: 1 b: 2
imfill(f, locations, conn) 将二值图洞填补

主要用于将洞填补,例如下面这个(其中,洞只亮的部分被暗的部分所包围的地方[不算背景边界])。

f = imread('coins.png');
f = im2bw(f);
g = imfill(f, 4, 'holes');
subplot(1, 2, 1), imshow(f), title('原图');
subplot(1, 2, 2), imshow(g), title('填补后');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
bwlabel(f) 将二值图分区(可以用来计数)

比如下面这个,可以数清楚硬币有10个!

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
[g, n] = bwlabel(f);

如果这个函数配合find使用,那么我就可以获得指定的区域的图片

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
[g, n] = bwlabel(f);
[w, h] = size(g);
l = zeros(w, h);
sw = sqrt(n);
sh = n / sw;
for i=1:n
    [c, r] = find(g(:) == i);
    % l = zeros(w, h); % 这句话让每次读取都独立显示
    l(c) = 1;
    subplot(floor(sw), ceil(sh), i), imshow(l), title(i);
end
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
sortrows对向量进行升序排序

这里写图片描述

unique对向量进行排序并去重

这里写图片描述

circshift对数组的行列进行移动

这里写图片描述

boundaries(f, conn, dir)跟踪f 的 外部边界

这里写图片描述

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
g = boundaries(f, 4, 'cw');
d = cellfun('length', g);
[max_d, k] = max(d);
v = g{k(1)};
[w, h] = size(f);
l = zeros(w, h);
l(v(:,1), v(:,2)) = 1;
subplot(1, 2, 1), imshow(f), title('原图');
subplot(1, 2, 2), imshow(l), title('边界最长的');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
bound2eight(v) 去除除了8链接外的像素

这里写图片描述

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
g = boundaries(f, 4, 'cw');
v = g{1};
h = bound2eight(v);
subplot(1, 2, 1), imshow(bound2im(v)), title('4|8链接');
subplot(1, 2, 2), imshow(bound2im(h)), title('8链接');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
bound2four(v) 去除除了4链接外的像素

该函数跟上面的差不多,要注意的就是,所有的8链接都是4链接, 但是反之不然。

bound2im(b, W, H, x, y) 在x, y 处创建一个大小为W * H 的图像,其中b是np*2的矩阵,代表坐标(值为1)

注意 这里的x/y 表示的是最小的x和y不是某个固定的坐标
用上面的例子来演示

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
g = boundaries(f, 4, 'cw');
d = cellfun('length', g);
[max_d, k] = max(d);
v = g{k(1)};
[w, h] = size(f);
subplot(1, 2, 1), imshow(f), title('原图');
subplot(1, 2, 2), imshow(bound2im(v, w, h, min(v(:, 1)), min(v(:, 2)))), title('边界最长的');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
bsubsamp(b, gridsep) 对单一边界进行二次取样

其中 gridsep 可以理解成二次取样的step数 为2 就是2个像素2个像素的跳着取样

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
g = boundaries(f, 4, 'cw');
d = cellfun('length', g);
[max_d, k] = max(d);
v = g{k(1)};
[w, h] = size(f);
subplot(1, 3, 1), imshow(bound2im(v)), title('原图');
subplot(1, 3, 2), imshow(bound2im(bsubsamp(v, 2))), title('gridsep 2');
subplot(1, 3, 3), imshow(bound2im(bsubsamp(v, 30))), title('gridsep 30');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
connectpoly(x, y) 将未连接的点连接起来,并且比原来更加平滑

x, y 为坐标,可以为数组,但是要一一对应

f = imread('coins.png');
f = im2bw(f);
f = imfill(f, 4, 'holes');
g = boundaries(f, 4, 'cw');
d = cellfun('length', g);
[max_d, k] = max(d);
v = g{k(1)};
[w, h] = size(f);
subplot(1, 3, 1), imshow(bound2im(v)), title('原图');
v = bsubsamp(v, 2);
subplot(1, 3, 2), imshow(bound2im(v)), title('gridsep 2');
subplot(1, 3, 3), imshow(bound2im(connectpoly(v(:, 1), v(:, 2)))), title('connectpoly');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
intline(x1, x2, y1, y2) 将二个点连起来,并返回这条线的向量
[x, y] = intline(0, 100, 0, 100);
imshow(bound2im(cat(2, x, y)));
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述

表示

链码

这里写图片描述
这个就是上面用的4连接和8连接

fchcode(b, conn, dir) 计算b的Freeman链码

这里写图片描述
这里写图片描述

f = imread('img19.tif');
h = fspecial('average', 9);
g = imfilter(f, h, 'replicate');
subplot(2, 3, 1), imshow(f), title('原图');
subplot(2, 3, 2), imshow(g), title('9*9平滑掩模后');
g = im2bw(g, 0.5);
subplot(2, 3, 3), imshow(g), title('0.5 阈值二值处理');
B = boundaries(g, 4, 'cw');
d = cellfun('length', B);
[max_d, k] = max(d);
b = B{k(1)};
[w h] = size(g);
% 这里不膨胀的话看不到- -
g = bound2im(b, w, h, min(b(:, 1)), min(b(:, 2)));
subplot(2, 3, 4), imshow(imdilate(g, ones(3, 3))), title('最长边界');
[s, su] = bsubsamp(b, 50);
g2 = bound2im(s, w, h, min(s(:, 1)), min(s(:, 2)));
subplot(2, 3, 5), imshow(imdilate(g2, ones(3, 3))), title('将边界二次取样');
cn = connectpoly(s(:, 1), s(:, 2));
g2 = bound2im(cn, w, h, min(cn(:, 1)), min(cn(:, 2)));
subplot(2, 3, 6), imshow(imdilate(g2, ones(3, 3))), title('将二次取样后的边界连接起来');
  • 输出:
    这里写图片描述
  • 输入:
    这里写图片描述
使用最小周长的多边形的多边形近似

首先要MMP和Sklansky方法
这里写图片描述
这里写图片描述
按上面所说MMP就是最小周长的多边形,SKlansky方法则根据上述四个特性(规则)来进行寻找。

接着就是寻找一个区域的MMP的步骤:
这里写图片描述
这里写图片描述
这里写图片描述
根据以上规则,得到的多边形就会越来越近似于最小周长。

按照上面的步骤,我们将学习M函数的MMP算法实现

以下二个函数将在下面一起举例

qtdecomp(B, threshold, [mindim maxdim]) 将图像分割成等大小的部分方块

注意 图片的长宽需要时2次幂

f = imread('img19.tif');
h = fspecial('average', 9);
f = imfilter(f, h, 'replicate');
f = im2bw(f, 0.5);
l = f(1:512, 1:512);
b = bwperim(l, 8);
Q = qtdecomp(b, 0, 2);
qtgetblk(B, Q, middim) 获得四叉树中的分解的块
f = imread('img19.tif');
h = fspecial('average', 9);
f = imfilter(f, h, 'replicate');
f = im2bw(f, 0.5);
l = f(1:512, 1:512);
b = bwperim(l, 8);
Q = qtdecomp(b, 0, 2);
[vals, r, c] = qtgetblk(b, Q, 2);
获得一个区域的边界的细胞墙
f = imread('img19.tif');
h = fspecial('average', 9);
f = imfilter(f, h, 'replicate');
f = im2bw(f, 0.5);
l = f(1:512, 1:512);
b = bwperim(l, 8);
Q = qtdecomp(b, 0, 2);
[vals, r, c] = qtgetblk(b, Q, 2);
l = zeros(512, 512);
for i=1:length(r)
    l(r(i), c(i)) = vals(1, 1, i);
    l(r(i) + 1, c(i)) = vals(2, 1, i);
    l(r(i), c(i) + 1) = vals(1, 2, i);
    l(r(i) + 1, c(i) + 1) = vals(2, 2, i);
end
subplot(1, 2, 1), imshow(f), title('原图');
subplot(1, 2, 2), imshow(l), title('分块后');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
函数inpolygon(X, Y, xy, yx)

这里写图片描述

函数minerpoly(B, cellsize) 计算MMP
f = imread('img20.tif');
subplot(3, 3, 1), imshow(f), title('原图');
B = im2bw(f);
subplot(3, 3, 2), imshow(B), title('二值图');
b = boundaries(B, 4, 'cw');
b = b{1};
[M, N] = size(B);
bim = bound2im(b, M, N, min(b(:, 1)), min(b(:, 2)));
subplot(3, 3, 3), imshow(imdilate(bim, ones(3, 3))), title('boundaries');
[x, y] =  minperpoly(B, 2);
b = connectpoly(x, y);
bim= bound2im(b, M, N, xmin, ymin);
subplot(3, 3, 4), imshow(imdilate(bim, ones(3, 3))), title('MMP 2');
[x, y] =  minperpoly(B, 3);
b = connectpoly(x, y);
bim= bound2im(b3, M, N, xmin, ymin);
subplot(3, 3, 5), imshow(imdilate(bim, ones(3, 3))), title('MMP 3');
[x, y] =  minperpoly(B, 4);
b = connectpoly(x, y);
bim= bound2im(b, M, N, xmin, ymin);
subplot(3, 3, 6), imshow(imdilate(bim, ones(3, 3))), title('MMP 4');
[x, y] =  minperpoly(B, 8);
b = connectpoly(x, y);
bim = bound2im(b, M, N, xmin, ymin);
subplot(3, 3, 7), imshow(imdilate(bim, ones(3, 3))), title('MMP 8');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
标记

标记是边界的一维函数的表示,主要思想就是将边界简化为一维函数,使其更加容易描述。

signature(b, x0, y0) 用于查找给定边界的标记

该函数的b需要必须是像素宽的边界,如boundaries获得的边界
这里写图片描述

cart2pol(X, Y) 将笛卡尔坐标转换为极坐标

这里写图片描述
这里写图片描述

标记
f = imread('img21.tif');
f = imdilate(f, ones(3, 3));
subplot(2, 2, 1), imshow(f);
B = boundaries(f, 4, 'cw');
d = cellfun('length', B);
[max_d, k] = max(d);
b = B{k(1)};
[st, angle, x0, y0] = signature(b);
subplot(2, 2, 3), plot(angle, st);

f = imread('img22.tif');
f = imdilate(f, ones(3, 3));
subplot(2, 2, 2), imshow(f);
B = boundaries(f, 4, 'cw');
d = cellfun('length', B);
[max_d, k] = max(d);
b = B{k(1)};
[st, angle, x0, y0] = signature(b);
subplot(2, 2, 4), plot(angle, st);
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
边界片段

这里写图片描述
使用regionprops函数(11.4.1)实现

骨骼

将一个结构细化的过程称为骨骼化。

bwmorph(f, ‘skel’, Inf) 骨骼化,在形态学中有讲过
f = imread('img23.tif');
f = tofloat(f);
subplot(2, 3, 1), imshow(f), title('原图');
h = fspecial ('gaussian', 25, 25);
g = imfilter(f, h, 'replicate');
subplot(2, 3, 2), imshow(g), title('25*25 高斯模糊');
g = im2bw(g, 1.5 * graythresh(g));
subplot(2, 3, 3), imshow(g), title('二值化');
g1 = bwmorph(g, 'skel', Inf) ;
subplot(2, 3, 4), imshow(g1), title('细化');
g2 = bwmorph(g1, 'spur', 8);
subplot(2, 3, 5), imshow(g2), title('去除毛刺 * 8');
g3 = bwmorph(s2, 'spur', 7);
subplot(2, 3, 6), imshow(g3), title('去除毛刺 * 7');
  • 输入:
    这里写图片描述
  • 输出:
    这里写图片描述
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值