数字图像处理--形态学
2019/4/11数字图像处理练习
一、柠檬纹理---顶帽、底帽
- se=strel(‘disk’,10);
SE = strel('disk',R,N) creates a disk-shaped structuring element, where Rspecifies the radius. N specifies the number of line structuring elements used to approximate the disk shape.
disk圆盘,帮助手册上显示strel(‘’,R,N);可以有两个参数,但指令提示只能有一个参数。有截图为证:
对于数值‘10’的具体意义看图:
很清晰很明白,具体描述出来的话应该是 N specifies the number of line structuring elements used to approximate the disk shape. 用来近似disk形状的结构元素的个数。
- 顶帽操作
Tophat=g-g_open;
运算:原图减去开运算
作用:去背景,使纹理更清晰
- 底帽操作
注意顶帽操作和底帽操作的对象都是灰度图。
代码1 lemon
clc,clear,close all;
f=imread('lemon.jpg');
figure,imshow(f);
g=rgb2gray(f);
se=strel('disk',10);
g_erode=imerode(g,se);
g_dilate=imdilate(g,se);
%用cat显示腐蚀和膨胀后的图,2为从左到右显示,1为从上到下显示,一张图片也可以显示。
ge=cat(2,g,g_erode,g_dilate);
figure,imshow(ge);
% ge2=cat(1,g,g_erode,g_dilate);
% figure,imshow(ge2);
g_open=imopen(g,se);
g_close=imclose(g,se);
goc=cat(2,g,g_open,g_close);
figure,imshow(goc);
%开运算和闭运算的区别:开运算去掉毛刺和噪声,闭运算填充小空洞
tophat=g-g_open;
figure,imshow(tophat);
bothat=abs(double(g)-double(g_close));
figure,imshow(bothat,[]);
- 得到计算器上的数字
%目标是得到计算器上的数字,想要什么把什么变成白色,已知顶帽操作去背景,使白色边界更清晰
clc,clear,close all;
f=imread('c.jpg');
%顶帽操作对象是灰度图,原图转换成灰度图之后边框仍是黑色,所以用255减
g=255-rgb2gray(f);
%腐蚀背景
gtophat=imtophat(g,strel('disk',3));
figure,imshow(gtophat),title('顶帽操作去背景');
%想要什么形状就用什么近似形状去腐蚀,数字找不到相似的形状而边框很明显,所以得到边框
se=strel('line',25,0);
gerode=imerode(gtophat,se);
figure,imshow(gerode),title('直线腐蚀留直线');
greborder=imreconstruct(gerode,gtophat);
figure,imshow(greborder),title('在顶帽后的图上重建');
des=gtophat-greborder;
figure,imshow(des);
result=cat(2,g,des);%使用cat时要求图片维度相同
figure,imshow(result);
思路:去背景--顶帽操作--直线腐蚀得到边框--在顶帽后的图上重建再相减--完事。
- 标记连通区
clc,clear,close all;
f=im2bw(imread('arrow.jpg'));
figure,imshow(f);
[l,num]=bwlabel(f);
%l是指整个0123456标记后的矩形大区域,num是连通区域的总数
%循环找到连通区标记为123456的部分,取中值标记
for i=1:num
[r,c]=find(l==i);
rbar=mean(r);
cbar=mean(c);
hold on;
plot(cbar,rbar,'r*');
end
- 数硬币
f=imread('coin.jpg');
bw=im2bw(f);
bw=imfill(bw,'holes');
imshow(bw);
[l,num]=bwlabel(bw);
for i=1:num
[r,c]=find(l==i);
mr=mean(r);
mc=mean(c);
hold on;
plot(mc,mr,'r*');
end
s=strcat('共有',num2str(n),'个硬币。');
display(s);
解决办法:plot(mc,mr,’r*’);标记的时候先上下再左右!!!
- 标记汉字
clc,clear,close all;
f=imread('xue.jpg');
bw=~im2bw(f);
%闭运算先膨胀后腐蚀,对汉字先做闭运算然后再用竖线膨胀
bw_close=imclose(bw,strel('disk',1));
bw_dilate=imdilate(bw_close,strel('line',10,90));
[l,n]=bwlabel(bw_dilate);
imshow(bw);
for i=1:n
[r,c]=find(l==i);
mc=mean(c);
mr=mean(r);
hold on;
plot(mc,mr,'r*');
end
s=strcat('共有',num2str(n),'个汉字哟!');
display(s);
小练习
clc,clear,close all;
f=imread('atmkey.jpg');
figure,imshow(f);
g=255-rgb2gray(f);
gtophat=imtophat(g,strel('disk',5));
figure,imshow(gtophat),title('顶帽操作去背景');
%直线腐蚀的目的是去掉除了线之外的东西
gerode=imerode(gtophat,strel('line',50,0));
figure,imshow(gerode),title('直线腐蚀');
gre=imreconstruct(gerode,gtophat);
figure,imshow(gre);
re=gtophat-gre;
figure,imshow(re);
PC键盘数字
clc,clear,close all;
f=imread('key.jpg');
g=255-rgb2gray(f);
gtophat=imtophat(g,strel('disk',10));
gerode=imerode(gtophat,strel('line',20,0));
grecon=imreconstruct(gerode,gtophat);
re=gtophat-grecon;
s=cat(2,gtophat,gerode,grecon,re);
figure,imshow(s);