基于MATLAB图像处理技术之轮廓提取
1.迭代阈值处理和平滑滤波法处理方式
- 处理思路:
1.读入图片: I=imread('1.jpg');
2.二值化处理: I1 = rgb2gray(I);
3.阈值处理:选用的迭代法,当然阈值处理需要选用合适才能成功。
4.滤波降噪:采用平滑滤波
5.边缘检测:
感觉canny和log比较好,这个可根据所选的测试材料的性质来确定。
6.最大连通域法截取最大的轮廓:
- 如果中间滤波处理的不是很完善,或者外界干扰性差,会引起所选轮廓缺失。除此之外就是图像自身因素。
话不多说,直接上代码
I=imread('1.jpg'); %读取图片
I1 = rgb2gray(I); %二值化处理:0/1
ZMAX=max(max(I1)); %取出最大灰度值
ZMIN=min(min(I1)); %取出最小灰度值
TK=(ZMAX+ZMIN)/2; %获得平均灰度值
%迭代阈值处理
bcal=1; %定义变量
ISIZE=size(I1); %读出图像大小
while(bcal)
iForeground=0; %定义前景和背景数
iBackground=0;
ForegroundSum=0; %定义前景和背景灰度总和
BackgroundSum=0;
for i=1:ISIZE(1)
for j=1:ISIZE(2)
tmp=I1(i,j);
if(tmp>=TK)
iForeground=iForeground+1;
ForegroundSum=ForegroundSum+double(tmp); %前景灰度值
else
iBackground=iBackground+1;
BackgroundSum=BackgroundSum+double(tmp);
end
end
end
ZO=ForegroundSum/iForeground; %计算前景和背景的平均值
ZB=BackgroundSum/iBackground;
TKTmp=uint8(ZO+ZB)/2;
if(TKTmp==TK )
bcal=0;
else
TK=TKTmp;
end %当阈值不再变化的时候,说明迭代结束
end
disp(strcat('迭代后的阀值:',num2str(double(TK))));
newI=im2bw(I,double(TK)/255);
subplot(1,2,1);imshow(I1);
xlabel('(a)原始图像');
subplot(1,2,2);imshow(newI);
xlabel('(b)迭代法分割效果图');
%采用平滑滤波降噪
J2=filter2(fspecial('average',5),newI)/255;
imshow(newI,[]);
title('平滑滤波后图像');
bw=imfill(newI,'hole'); %填充噪点轮廓
isuo=imresize(bw,0.25,'bicubic');
ecanny=edge(isuo,'canny'); %canny算子检测
figure,imshow(ecanny),title('边缘检测图像');
if length(size(ecanny))>2
end
f=bwareaopen(ecanny,50);
figure,imshow(f),title('杂点消除');
%二次二值化处理
if ~islogical(f)
imBw = im2bw(f); %转换为二值化图像
else
imBw =f;
end
imBw = im2bw(f); %转换为二值化图像
%使用最大连通域法进行最后的分割---轮廓提取
imLabel = bwlabel(imBw); %对各连通域进行标记
stats = regionprops(imLabel,'Area'); %求各连通域的大小
area = cat(1,stats.Area);
index = find(area == max(area)); %求最大连通域的索引
img = ismember(imLabel,index);
figure,imshow(img),title('检测图像');
基于快速傅里叶变换法之图像处理
- 1.这里采用的是傅里叶变换技术,在噪点消除上有明显的不同,其次就是在杂点去除过程中有明显的差别。这样更有利于图像全部像素点的采集处理。
- 2.由于傅里叶变换需要将每个像素点都要一次一次的计算,使得程序运行起来相对吃力一点。所以后期的优化工作需要采用其他更高效的办法进行测试比较。
ims=imread('0.jpg');
im=rgb2gray(ims);
d0=50; %阈值
img_noise=imnoise(im,'salt'); % 加椒盐噪声
%选取一种噪声,便于后续操作
%img_noise=imnoise(img_origin,'gaussian'); % 加高斯噪声
img_f=fftshift(fft2(double(img_noise))); %傅里叶变换得到频谱
[m n]=size(img_f);
m_mid=fix(m/2); %选取一种取整方式,这里选的比较简单
n_mid=fix(n/2);
img_lpf=zeros(m,n);
for i=1:m
for j=1:n
d=sqrt((i-m_mid)^2+(j-n_mid)^2); %理想低通滤波,求距离
if d<=d0
h(i,j)=1;
else
h(i,j)=0;
end
img_lpf(i,j)=h(i,j)*img_f(i,j);
end
end
img_lpf=ifftshift(img_lpf); %反傅里叶变换
img_lpf=uint8(real(ifft2(img_lpf))); %取实数部分
subplot(2,2,1);imshow(img_origin);title('原图');
subplot(2,2,2);imshow(img_noise);title('噪声图');
subplot(2,2,3);imshow(img_lpf);title('理想低通滤波');
[thr,sorh,keepapp]=ddencmp('den','wv',img_lpf);
ixc=wdencmp('gbl',img_lpf,'sym4',2,thr,sorh,keepapp);
figure,imshow(ixc),title('消噪后图像 ');
isuo=imresize(ixc,0.25,'bicubic');
g=imdilate(isuo,strel('disk',2));
figure,imshow(g),title('增强图像');
ecanny=edge(g,'canny');
figure,imshow(ecanny),title('边缘检测图像');
if length(size(ecanny))>2
end
f=bwareaopen(ecanny,50);
figure,imshow(f),title('杂点消除');
if ~islogical(f)
imBw = im2bw(f); %转换为二值化图像
else
imBw =f;
end
imBw = im2bw(f); %转换为二值化图像
imLabel = bwlabel(imBw); %对各连通域进行标记
stats = regionprops(imLabel,'Area'); %求各连通域的大小
area = cat(1,stats.Area);
index = find(area == max(area)); %求最大连通域的索引
img = ismember(imLabel,index);
figure,imshow(img),title('检测图像');
总结:
1.学习过程中需要多思考多总结。
2.后期优化处理需要做到更切合实际场景,敢于尝试失败。