2021-07-08

山东大学暑期项目实训

昨天分了任务做了一下人工的图像分拣,发现很多的图像效果并不是很良好。感觉是图像分割的效果不大好,导致骨干提取的效果不是很好。
同时,组长分配的任务是是去小邻域。二值化分割图像的结果,除了有我们想要的结果意外,还有很多其他的小邻域的噪声,关键就是如何找到算法去除这些小邻域。

开闭操作的去除方法

图像处理提到过的,利用形态学的方法,用膨胀和腐蚀对图像处理。其中,先腐蚀再膨胀的开操作,可以去除一些小邻域;先膨胀再腐蚀的闭操作可以填补图像中的空缺。
不过难点在于如何构造操作使用的矩阵
一开始使用的3*3的矩阵进行操作,感觉效果不是很明显,而且,很多小邻域都明显大于这个,去噪效果并不是很理想。
随后我浏览到了别的方法

最大连通域方法

转换了一下思路,并不去对小邻域进行处理,而是对所有的邻域进行划分,然后找最大的邻域,一般来说我们的结果就是二值图中最大的连通域。按照这个思路去寻找matlab中的相关方法,matlab中似乎对相关的函数有所实现,我的算法参考这里link
可见相关的连通域算法matlab中基本都有相关的实现
那么我们要做的事情比较简单了
1,提高图像分割的质量
2,使用开闭操作,尽量使小邻域边缘圆滑,不和主干部分相连,然后使用几次闭操作尽量尽量让主干部分连接在一起
3,寻找并保留最大的连通域,即是结果

%默认8领域
se=[0,1,0;
    1,1,1;
    0,1,0];
nse=mod(se+1,2);
I=imread('');
[width,height,dimension]=size(I);
subplot(1,4,1);
imshow(I);
title('原图');
I1=rgb2gray(I);
I1=tofloat(I1);
I2=stdfilt(I1);
m=imfilter(I1,1/9*ones(3),'replicate');
m2=mean2(I1);
I3=(I1>=28*I2)&(I1>=0.8*m);% (I1>15*I2)&(I1>0.4*m);
I9=uint8(ones(width, height ,dimension));
I9=I9*255;
for i=1:height
    for j=1:width    
if(I3(j,i)==0)
    I9(j,i,:)=uint8(I(j,i,:));
end
    end
end

subplot(1,4,2);
imshow(I3);% this is the result of the sf
title('8邻域局部阈值结果');

I5=close(close(I3));
subplot(1,4,3);
imshow(I5);
title('两次闭操作尽量连通');
I6=maxLian(I5);
subplot(1,4,4);
imshow(I6);
title('最大连通域结果');


function result=close(img)
se=[0,1,0;
    1,1,1;
    0,1,0];
fo=imopen(img,se);%直接开运算
result = fo;
end

function [out,revertclass] = tofloat(inputimage)

% 类型转换
% 单纯的取 x 用的匿名函数句柄(玩的有点花)
identify = @(x) x;
% 将输入转换为单精度的函数句柄
tosingle = @im2single;

table = {'uint8',tosingle,@im2uint8 

         'uint16',tosingle,@im2uint16 

         'logical',tosingle,@logical

         'double',identify,identify

         'single',identify,identify};
% strcmp(s1,s2),输入字符串的数组可以说任意类型组合
% find 找出其中的真值
classIndex = find(strcmp(class(inputimage),table(:,1)));

if isempty(classIndex)

    error('不支持的图像类型');

end
% 找到对应的转换类型
out = table{classIndex,2}(inputimage);
% 记录对应逆转换类型
revertclass = table{classIndex,3};
end
function img=maxLian(I)
se=[1,1,1;
    1,1,1;
    1,1,1];
if length(size(I))>2
    I = rgb2gray(I);
end
if ~islogical(I)
    imBw = imbinarize(I);                        %转换为二值化图像
else
    imBw = I;
end
imBw = im2bw(I);                        %转换为二值化图像
imBw=imcomplement(imBw);
%imBw=imopen(imBw, se);
imBw=imclose(imBw,se);
imBw=imopen(imBw,se);

imLabel = bwlabel(imBw);                %对各连通域进行标记
stats = regionprops(imLabel,'Area');    %求各连通域的大小
area = cat(1,stats.Area);
index = find(area == max(area));        %求最大连通域的索引
img = ismember(imLabel,index);          %获取最大连通域图像
end

仍是在原先我使用的8邻域局部算法的基础上进行处理,这次我将参数从15调高到28,图像尽量存在更多的特征,能够更好的连通。
这里的开闭运算用的矩阵没有统一…方法一个用的matlab自带的一个是自己添加的。
对图像的开闭操作完成连通域的整合和然后提取即可。个人感觉效果还可以

但是仍不可避免的,非常的吃图像分割的效果
而且图像分割效果差点,原来的二值化结果是比较割裂的情况下,那么连通域的结果将是比较毁灭的情况
matlab的代码需要转换到python,这是比较头疼的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值