任务要求:

1.将图像二值化,突出叶子
2.将图像中叶子的轮廓找出来
3.将叶子的轮廓用傅里叶方式表述
4.给出去掉高频后重构的轮廓

实现

首先分析思路

该问题分为两个部分,图像分割和边缘表达,图像分割要求将叶子和背景完全分离,边缘表达要求对按顺序提取出轮廓进行表述

图像分割:

1.首先将图像转换为灰度图像,然后利用最大类间方差法求得阈值,然后将其二值化,此时的结果不是太好。

在这里插入图片描述

2.故要对其进行一系列操作,孔洞填充+膨胀直到将内部的黑色全部消去(轮廓好像有点变形)

在这里插入图片描述

3.提取出边界

在这里插入图片描述

clc;clear;
A=imread('1.jpg');
A=rgb2gray(A);
T=graythresh(A);
B=im2bw(A,T);
B(500:end,700:end)=1;
mask=[0,1,0;1,1,1;0,1,0]; %膨胀操作的结构元
SE=strel('arbitrary',mask);
B=~B;
B=imfill(B,'holes');
B=imdilate(B,SE);
B=imdilate(B,SE);
B=imdilate(B,SE);
B=imerode(B,SE);
B=imfill(B,'holes');
E=bwperim(B,8); 
imshow(E);

边缘表达:

1.按逆时针(or顺时针)提取出轮廓的坐标,一个是行向量,一个是列向量
2.算出行向量的均值和列向量的均值,利用行的波动向量和列的波动向量构建一个复数向量
3.对该复数向量做fft,然后取其低频分量(注意复数向量的频谱不是对称的,然后作一个低通滤波,注意低通滤波一定是中心对称的),然后反傅里叶变换
4.实部向量加上之前的均值即为滤波后的行向量,虚部向量加上之前的均值即为滤波后的列向量
5.构建一张新的背景图,在滤波后得到的位置标1即可得到平滑后的轮廓

[m,n]=find(E==1);
contour = bwtraceboundary(E,[m(1),n(1)],'W',4); 
m=contour(:,1);
n=contour(:,2);
sr_mean=mean(m);
si_mean=mean(n);

figure;
s=(m-sr_mean)+1i*(n-si_mean);
s_f=fft(s);

sav=0.2;
tt=double(int32(sav*length(m)/2));
s_ff=s_f.*[ones(1,tt),zeros(1,length(m)-2*tt),ones(1,tt)]';
plot(abs(s_ff));
s_c=ifft(s_ff);
x_cd=real(s_c);
y_cd=imag(s_c);

x_c=abs(double(int32(sr_mean+x_cd)));
y_c=abs(double(int32(si_mean+y_cd)));

M=zeros(600,800);
for i=1:length(x_c)
    M(x_c(i),y_c(i))=1;
end
figure;
imshow(M);

结果:

在这里插入图片描述

这里的轮廓跟踪直接用的库函数。。。