吸管流水线机器视觉检测Demo--by Matlab

吸管流水线机器视觉检测Demo MATLAB实现【1】--by 少少东

  最近一周,在笔者的图像处理上,老师布置了一项有趣的大作业,也是项目的简单一部分,经过两个晚上近五个小时的学习编写和实验,终于取得了一些简单基本的成果。现在梳理一遍学习思路,和大家分享一下学习的过程的一些问题和收获。
吸管流水线检测

  首先上图。如图,笔者理解这是一个流水运送的过程。经过初步的观察,可以发现:吸管分为两段,一段白色的非常明显,但是还有黑暗中藏着的一段透明的兄弟,如果直接用普通的阈值分割出吸管部分显然是不行的,要求要检测出两段吸管的位置和长度直径参数。
  思路非常简单,将图像分为两个部分处理,笔者分别命名为lightErea和darkErea,具体的分割方法会在后文贴出来,显然手动分割的方法不符合我们自()动()检测的要求,要做出一个自动化的方法来。

阈值分割

  笔者尝试了几种阈值分割的方法,其中固定阈值的鲁棒性太低,不做考虑,用大津法,分水岭法等尝试后,发现大津法的相对效果最好,matlab中也有现成的函数可以调用非常方便:

level=graythresh(src);     %确定灰度阈值,使用大津法
BW = im2bw(src,level);     %二值化分割

 分割效果如下:
在这里插入图片描述

按连通域面积滤除金属反光干扰

  可以看到算法将其中吸管较好的分割了出来,但是由于金属反光严重,有大量干扰的连通域,其实看一下,吸管的连通域非常巨大,随即想到matlab处理连通的神级函数regionprops,采集到每个连通域的大小,取最大的四个即可,代码在文后子函数中,可以一览无余。

处理后效果:
在这里插入图片描述
  可以看到留下了清晰的四根吸管,但是还是由于某个金属部分的反光与习惯相连,所以无法完全分割出吸管的轮廓,这部分留下来下次处理。

黑暗部分检测并拼接

  接下里处理透明部分的吸管。由上面处理的图片其实只要找到吸管右端最突出的地方,就可以把明暗两个部分分割开来,代码见文后darkSeparate,此时分割出来的黑暗部分,透明吸管也是可以通过大津法分割出来的,只不过和明亮部分的阈值就完全不同了:
处理后效果:
在这里插入图片描述

  然后就很简单了,将两个图像拼接起来就可以了,代码在主函数中,并且可以将此时的二值图和原图相与,就得到完整的吸管部分,本此由于时间关系,先到此为止,下次再写后续的处理。
拼接后效果:

在这里插入图片描述

最终效果:
在这里插入图片描述

          再见鸭<挥手挥手>

代码部分

主函数部分

clear all;clc;close all;
%___________全局变量部分______________%
global srcOtsu;
global darkCol;
global srcCol;
%_____________主函数部分______________%
%info =imfinfo('suckerBar.png');
src = imread('4.bmp');  %读入待处理图片,注意:此处为灰度图,所以不用做rgb2gray转换,有的图片要下面注释一步
%src = rgb2gray(src);
srcOtsu = Otsu(src);    %调用子函数记性大津法二值化分割
lightErea = MaxOfErea(srcOtsu);  %调用子函数保留最大的四个区域
darkErea = darkSeparate(src);    %对黑暗部分使用大津法二值化分割
darkErea = Otsu(darkErea);
%____________图像显示结果______________%
subplot(2,3,1),imshow(src),title('原始图像');
subplot(2,3,2),imshow(srcOtsu),title('总体进行Otsu');
subplot(2,3,3),imshow(lightErea),title('过滤掉多余部分');
subplot(2,3,4),imshow(darkErea),title('分割出较暗的部分');
lightErea( : ,darkCol-10:srcCol)=darkErea(:,:);  %将明亮部分与黑暗部分拼接
subplot(2,3,5),imshow(lightErea),title('拼接效果图');
%____________在原图上划分出有效的吸管位置________%
uDst = im2uint8(lightErea)/255;                   %将二值图转化为Unit8格式
dst = uDst .* src;                             %与待处理图片相与
subplot(2,3,6),imshow(dst),title('最终结果');

其中有三个子函数,分别为:Otsu,MaxOfErea和darkSeparate,下面分为贴出,注释详尽:

function BW = Otsu(src)

level=graythresh(src);     %确定灰度阈值,使用大津法
BW = im2bw(src,level);     %二值化分割
end
function lightErea = MaxOfErea(tmp)

imLabel = bwlabel(tmp);% 对连通区域进行标记
stats = regionprops(imLabel,'Area'); %使用regionprops函数,读出每一个连通域的面积
[~,index]=sort([stats.Area],'descend'); %排序函数,descend为降序,具体可以阅读送sort文档
lightErea=ismember(imLabel,index(1:4));  %取前四个最大的连通域
end   
%——————将图像的明暗区域完整的分开——————%
function darkErea = darkSeparate(tmp)
%___________全局变量部分______________%
global srcOtsu;
global darkCol;
global srcCol;
%以列倒退查找,找到明亮处与黑暗处的分界点,即第一个1.使用find函数。复杂又慢。
[~,darkCol]=find(srcOtsu,1,'last') %从后向前,找到第一个非零的项。
[~, srcCol]= size(tmp)          %获取输入图像的尺寸
darkErea = tmp( : ,darkCol-10:srcCol);       %精密截取黑暗部分的图像
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值