2021-03-02

机器视觉的作业

基于matlab的一个代码作业,其中借鉴了网络一个人的代码,对它进行了更加符合作业要求的改写。(找不到之前年前写作业的时候的那个文章了,其中有一段我认为写的不太对,运行起来总有问题)

(1)图片预处理:

首先需要将图片进行预处理,使用函数rgb2gray将图片转化为二值图,使所有像素点的值位于0-255(黑到白),显示灰度直方图。直方图描述了该图像中关于颜色的数量特征,可以反映图像颜色的统计分布和基本色调,一般情况下,由于图像上的背景和前景物体颜色分布明显不同,从而在直方图上会出现双峰特性。阈值分割的基本思想是确定一个阈值,然后把每个像素点的灰度值和阈值相比较,根据比较的结果把该像素划分为两类——前景或背景。图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。通过阈值分割达到去除背景的目的,流程图:

(2)找出胶囊位置 :

将图片进行预处理后,胶囊区域分割为不同的连通域。判断连通域个数来判断胶囊的粒数,通过与正确粒数对比,判断胶囊是否缺失。由于蓝白胶囊的白色区域与药板底色一样,无法判断白色部分大小及位置,蓝色胶囊仅判断蓝色区域。然后对连通域进行框选,确定胶囊具体位置,且标出质心位置,以便后续对胶囊种类的判断。
图二
3.判断胶囊种类

判别胶囊种类目前可以通过连通域大小、颜色识别的方法。在MATLAB中一幅RGB图像可表示为一个MN3的三维矩阵。其中每一个彩色像素都在特定空间位置的彩色图像中对应红、绿、蓝3个分量。分量图像的数据类型决定了他们的取值范围。若一幅RGB图像的数据类型是uint8,则每个分量图像的取值范围是[0,255]。颜色识别方法为,读取该矩阵点的B分量,将上一步得到的质心坐标取出,判断质心附近的像素,通过筛选蓝色像素的方法,判断蓝色胶囊的个数。

二:具体流程

(1)读取待处理彩色药板图像,获取目标图像。
在这里插入图片描述
(2)图像预处理,原始彩色图像转化为灰度图。
在这里插入图片描述
(3)通过阈值分割,去除背景。
在这里插入图片描述
在这里插入图片描述
(4)再次根据阈值,判断出黄颜色区域。
在这里插入图片描述
(5)对图片进行取反,,利用闭循环先膨胀后腐蚀,将胶囊边缘处理的平滑整齐。
在这里插入图片描述
(6)将药板填充,确定药板边缘。
在这里插入图片描述
(7)通过三角形定理,确定边缘倾斜角度,将图片进行旋转。
(8)由于处理后噪点过多,再次进行闭运算,去除小的噪点。
在这里插入图片描述
(9)划分连通域,将每个连通域用最小矩阵框出,并标出矩阵质心。
在这里插入图片描述
(10)用颜色识别确定胶囊种类。
在这里插入图片描述
(11)计算各类胶囊个数,输出结果至图片下方以及命令执行窗口。
在这里插入图片描述
以下为代码,图片是网络随便找的,代码中有些数据仅针对该图片管用,如果换一个图,可能降噪不理想,提取出各种大大小小的区域。

clc; close all;clear all;                     %清除之前所有信息
%%
%图片初步处理
I=imread('089.png');             %打开图片
a=rgb2gray(I);                %进行灰度处理
figure                        %第一张图
imshow(I); title('原图');     %显示原图
figure                        %第二张图
imshow(a); title('灰度图');   %显示灰度处理后的图片
%%
%将背景去掉
x=size(a,1);        %把a的行赋值给x
y=size(a,2);        %把a的列赋值给y
g=zeros(x,y);       %建立一个空矩阵g,行数是x,列数是y
for i=1:1:x         %for循环,a矩阵中背景颜色小于120的点变成0(白到黑 0-255for j=1:1:y
    if(a(i,j)<120)
       g(i,j)=0 ;
    else
      g(i,j)=255;  
    end   
    end
end
%%
figure 
imshow(g);
title('过滤背景');
I=imread('089.png');
[m,n,d]=size(I);   %提取黄色区域
for i=1:m
    for j=1:n
        if(I(i,j,1)>150 && I(i,j,1)<256)&&(I(i,j,2)>150 && I(i,j,2)<255)&&(I(i,j,3)>0 && I(i,j,3)<100);   %找出黄色像素
        g(i,j)=0;
        end
    end
end
figure,imshow(g);
title('去除彩色区域');
%%
%图片闭运算处理胶囊位置
fa=1-g;     %取反
se=strel('square',5);     %将胶囊的边缘平滑整齐
closeg=imclose(fa,se);    %填充图片,闭运算先膨胀后腐蚀
closeg=1-closeg;
figure,
imshow(closeg);
title('闭运算后') 
%药板边缘确定
fillg=zeros(x,y);           %又建立了一个空矩阵
fillg=imfill(g,'holes');    %填充了图片
BW=edge(fillg,'roberts');   %边缘提取
figure,
imshow(BW);
title('药板边缘确定');
%将胶囊的边缘平滑整齐
%%
tiqu1=(y-1)/2-150;
tiqu2=(y-1)/2+150;
cishu1=1;
cishu2=1;
x1=0;
x2=0;
for i=1:1:x
    if cishu1==1
        if g(i,tiqu1)==255
            x1=i;
            cishu1=0;
        end
       
    end
end
for i=1:1:x
    if cishu2==1
        if g(i,tiqu2)==255
            x2=i;
           cishu2=0;
        end
    end
end
theta=atan(abs(x1-x2)/abs(tiqu2-tiqu1))*180/pi;   %算出旋转度数
%%
S = imrotate(BW,-theta);
A= imrotate(closeg,-theta);
B= imrotate(fillg,-theta);
I= imrotate(I,-theta);
BW=imrotate(BW,-theta);
C=B-A;
figure
imshow(C);
title('提取胶囊轮廓');
%%
%由于处理过后噪点太多,取反闭运算,再取反
C=1-C;
se=strel('square',5); 
closeg=imclose(C,se); 
closeg=1-closeg;   %再次闭运算,先膨胀
figure,
imshow(closeg);
title('边缘检测后再次闭运算')
C=closeg;
%%
%标签定位
fill_write=B;
figure
imshow(B);title('确定药板位置');
start1=0;
start2=0;
sta_x1=0;
sta_x2=0;
sta_y=0;
for i=1:1:y
    if(start1==1)
        if(BW(i,y/2)==1)
            sta_y=i;
            start1=1;
        end   
    end
end
for i=1:1:x
    if(start2==1)
        if(BW(i,x/2)==1)
            sta_x1=i;
            start2=1;
            i=i+20;
        end
    end
    if(start2==1)
        if(BW(i,x/2)==1)
            sta_x2=i;
            start2=2;
            i=i+20;
        end
    end
end
sta_x=sta_x2-sta_x1;
for j=(sta_y+round(sta_x/3)):1:y
   for i=1:1:x
    %fill_write(i,j)=0;
   end
end
img = regionprops(fill_write,'boundingbox'); 
locate = cat(1,img.BoundingBox);
%%
T = graythresh(C);           %找到合适阈值
bw_img = im2bw(C, T);        %图片进行二值化处理
img_reg = regionprops(bw_img,'area', 'boundingbox','Centroid');  %regionprops,分割连通域,求出质心
areas = [img_reg.Area];  
rects = cat(1,img_reg.BoundingBox);
zhixin = cat(1,img_reg.Centroid);
figure;
imshow(I); title('识别结果')
%%
for i = 1:size(rects, 1)  %size查询矩阵维数
    rectangle('position', rects(i, :), 'EdgeColor', 'r');%rectangle绘制矩形
    hold on
    plot(zhixin(i,1),zhixin(i,2),'ob');  %在中心处画出空心圆
    hold on
end 
for i = 1:size(locate, 1)            %圈出药板位置
    rectangle('position', locate(i, :), 'EdgeColor', 'r');
        hold on
end
%%
%确定药丸颜色
gre=0;    %绿色药丸个数
blu=0;    %蓝色药丸个数
zhixin1=ceil(zhixin);    %质心坐标取整
[q,~]=size(zhixin);      %判断质心点上下20个像素是否为绿色或蓝色
for i=1:q
    xx=zhixin1(i,1);
    yy=zhixin1(i,2);
    if I(yy,xx,3)>130||I(yy+20,xx,3)>130||I(yy-20,xx,3)>130
        blu=blu+1;
    else
        gre=gre+1;
    end
end
%正确药板数为:12
right=12;
quie=right-q;
if quie==0
    text(150,380,'药板无药粒缺失');
else
    text(150,380,'药板缺失药粒,缺失个数为:');
    text(360,380,num2str(quie));
end
text(150,400,'绿色胶囊个数为:')
text(300,400,num2str(gre));
text(150,420,'蓝色胶囊个数为:')
text(300,420,num2str(blu));
%%
qts={'缺失个数为:'};
qs=num2str(quie);
gts={'绿色胶囊个数为:'};
as=num2str(gre);
bts={'蓝色胶囊个数为:'};
bs=num2str(blu);
gts=[qts qs;gts as;bts bs];
gts
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值