基于matlab的颜色识别与提取_机器视觉综合实训有得

一、课程任务设计要求

(1)在编写摄像头采集图像程序,能够对图像进行采集、保存处理;
(2)对采集图像进行预处理,RGB 到 YCBCR 的色彩空间转换,用各个通道的阈值对图像进行二值化;形态学处理:腐蚀、膨胀、孔洞填充,连通区域提取,识别出指定的颜色区域;
(3)能够识别到多个颜色并进行分割;
(4)设计 GUI 界面,能够通过界面进行图像采集、识别、输出信息。

二、实现

1.对图像的采集与保存处理
obj= videoinput('winvideo',2,'RGB24_800x600');  %设备采集图像输入,适配器名称,图像格式
src = getselectedsource(obj); 
src.ColorEnable = 'off';

frame = getsnapshot(obj);
imshow(frame);%显示图片frame
mkdir('D:\image\1');%创建保存的路径
imwrite(frame,'D:\image\1\snap6.jpg','jpg');
(1)videoinput函数

用于获取采集到的视频
OBJ = videoinput(adaptorname,deviceID,format)
adaptorname:适配器名称
deviceID:设备ID
format:视频格式

命令行输入imaqhwinfo可获取相机的适配器名称,输入
win_info = imaqhwinfo(‘winvideo’) %适配器名称随上步查询结果变动
可查询设备ID(通常如果是笔记本的话会出现两个ID,通常相机的设备ID是2)
输入win_info.DeviceInfo.SupportedFormats可查询相机支持的编码格式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)getsnapshot函数

用于在视频中捕捉得到一个图片

(3)imshow函数

用于显示图片,通常与figure搭配使用
例:figure,imshow(I)%创建一个新的窗口显示图片

(4)mkdir函数

用于创建一个新的文件夹,绝对路径和相对路径都可

(5)imwrite函数

用于保存图片
imwrite(a,filename,format)
a:图片名称
filename:保存路径
format:保存的格式

2.对采集图像进行预处理,RGB 到 YCBCR 的色彩空间转换,用各个通道的阈值对图像进行二值化
flag = imread('D:\image\1\snap6.jpg');
YCBCR = rgb2ycbcr(flag);%转换到YCBCR空间

%用各个通道的阈值对其进行二值化处理
Y_MIN = 0;  Y_MAX = 256;
Cb_MIN = 100;   Cb_MAX = 127;
Cr_MIN = 138;   Cr_MAX = 170;
threshold=roicolor(YCBCR(:,:,1),Y_MIN,Y_MAX)&roicolor(YCBCR(:,:,2),Cb_MIN,Cb_MAX)&roicolor(YCBCR(:,:,3),Cr_MIN,Cr_MAX);
(1)imread函数

用于读入将被处理的图片
obj=imread(filename.fmt);

(2)rgb2ycbcr函数

2其实就是to,该函数用于将RGB图片转换为YCBCR图片
那为什么要转换为YCbCr图片呢?
用于压缩图片!因为人的眼睛对YCbCr色彩空间编码的视频中的Y分量更加敏感,而Cb和Cr的微小变化不会引起视觉的不同。因此我们可以通过对Cb和Cr分子进行采样来减小图像的数据量,使得图像对于储存需求和传输带宽的要求大大降低,从而达到在完成图像压缩的同时也保证视觉上几乎没有损失。
其中,Y(Luminance):明亮度和浓度
Cb(Chrominance-Blue):颜色中的蓝色浓度偏移量
Cr(Chrominance-Red):颜色中的红色浓度偏移量
在这里插入图片描述

(3)roicolor函数

根据各个通道的阈值进行二值化

3.形态学处理:腐蚀、膨胀、孔洞填充,连通区域提取
%进行形态学处理:腐蚀、膨胀、孔洞填充
erodeElement = strel('square', 3) ;
dilateElement=strel('square', 8) ;
threshold = imerode(threshold,erodeElement);%腐蚀
threshold=imdilate(threshold, dilateElement);%膨胀
threshold=imfill(threshold,'holes');%填充


%连通区域的选取
gray_img = rgb2gray(flag);
T = graythresh(gray_img); %得到一个阈值
bw_img = im2bw(gray_img, T); %转化为二值图像
img_reg = regionprops(bw_img,  'area', 'boundingbox');
areas = [img_reg.Area];%各个区域的像素总数
rects = cat(1,  img_reg.BoundingBox);%各部分的最小矩形
figure(1),
imshow(bw_img);
for i = 1:size(rects, 1)     %获取行数
    rectangle('position', rects(i, :), 'EdgeColor', 'r');
end

在这里插入图片描述

(1)regionprops函数

即用来度量图像区域属性的函数,其属性包括:Area,EquivDiameter,MajorAxisLength,BoundingBox,EulerNumber,MinorAxisLength,Centroid,Extent,Orientation,ConvexArea,Extrema,PixelIdxList,ConvexHull,FilledArea,PixelList,ConvexImage,FilledImage,Solidity,Eccentricity,Image

Area:计算出在图像各个区域中像素总个数。
BoundingBox:是1行ndims(L)*2列的向量,即包含相应区域的最小矩形。其值包括了矩形的起点的x,y坐标以及矩形的高与宽。
【关于更多参数的详解参照这位大神的:https://langbin.blog.csdn.net/article/details/49886787

img_reg = regionprops(bw_img, ‘area’, ‘boundingbox’);%只计算area和boundingbox两个属性
img_reg = regionprops(bw_img, ‘basic’);%计算area,boundingbox,centroid三个属性
img_reg = regionprops(bw_img, ‘all’);%计算全部属性

(2)cat函数

用于串联数组或矩阵,并且串联的数组或矩阵的维度要一致
C = cat(dim, A1, A2, A3, …)
例:
【此例来自这位大神:https://blog.csdn.net/qing101hua/article/details/45559377

>> A = [1 2; 3 4];
>> B = [5 6; 7 8];
>> A
A =
    1     2

    3     4
>> B
B =
    5     6

    7     8

>> cat(1, A, B) %按列连接(列数相同)
ans =
    1     2

    3     4

    5     6

    7     8

>> cat(2, A, B) %按行连接(行数相同)
ans =
    1     2     5     6

    3     4     7     8

>> cat(3, A, B) %合成效果如下图
ans(:,:,1) =
    1     2

    3     4
ans(:,:,2) =
    5     6

    7     8
(3)figure函数

figure; %创建一个新的窗口
figure(2);%窗口的命名为2,且窗口的命名不可以是0
figure(‘name’,‘show’);%窗口命名为show

(4)size函数

用于获取矩阵的行数和列数
<1>s=size(A); %返回一个行向量,该行向量的第一个元素是矩阵的行数,第二个元素是矩阵的列数
<2>[r,c]=size(A); %size函数将矩阵的行数返回到第一个输出变量r,将矩阵的列数返回到第二个输出变量c
<3>size(A,n); %返回矩阵的行数或列数
例:raw=size(A,1); %返回的时矩阵A的行数
col=size(A,2); %返回的时矩阵A的列数

(4)rectangle函数

用于创建二维矩阵对象
rectangle(‘Position’,[x y w h]) %从点(x,y)开始绘制一个宽w高h的矩形
rectangle(‘Position’,[x y w h],‘Curvature’,[a,b]) %x方向上的曲率为a,y方向上的曲率为b
rectangle(‘position’,…
[1,1,5,5],‘curvature’[1,1],‘edgecolor’,‘r’,‘facecolor’,‘g’);

%‘position’,[1,1,5,5]表示从(1,1)点开始高为5,宽为5;
‘curvature’,[1,1]表示x,y方向上的曲率都为1,即是圆弧;
‘edgecolor’,'r’表示边框颜色是红色;
‘facecolor’,'g’表示面内填充颜色为绿色。

4、能够识别到颜色并进行分割

【此算法来自这位大神:https://blog.csdn.net/qq_44894692/article/details/94359999

flag_hsv = rgb2hsv(flag); % 将图像的rgb色彩空间转化至hsv色彩空间     
flag_new = 255*ones(size(flag));% 创建一个白色图像,将特定颜色提取到此处
flag_new_hsv = rgb2hsv(flag_new);% 将该图像转至hsv色彩空间


%提取绿色部分
[row, col] = ind2sub(size(flag_hsv),find(flag_hsv(:,:,1)>0.15...
& flag_hsv(:,:,1)< 0.48 & flag_hsv(:,:,2)>0.16 & flag_hsv(:,:,3)>0.18));% 找出图像中绿色的像素
% 将图像中的绿色像素复制到刚才新建的白色图像中
for i = 1 : length(row)
    flag_new_hsv(row(i),col(i),:) = flag_hsv(row(i),col(i),:);
end
flag_green = hsv2rgb(flag_new_hsv);% 将提取出来的绿色,转化至rgb空间,进行展示
figure(2),imshow(flag_green);title('green_part');

在这里插入图片描述

其原理是将rgb转为hsv,这样,对颜色的判断就只需要对h通道进行判断即可。
何为HSV?
H(Hue):色调
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°;它们的补色是:黄色为60°,青色为180°,紫色为300°。在matlab是将对应颜色的角度值除以360°以得到一个0~1中的对应值。
S(Saturation):饱和度
表示颜色接近光谱色的程度。通常取值范围为0~1,值越大,颜色越饱和。
V(Value):明度
表示颜色明亮的程度,通常取值范围为0(黑)~1(白)。
下面这个图就很形象地表明他们的关系:
在这里插入图片描述
例程中是用于检测绿色,如果检测其他颜色:
[row, col] = ind2sub(size(flag_hsv),find((flag_hsv(:,:,1)>0.00…
& flag_hsv(:,:,1)< 0.03) |( flag_hsv(:,:,1)>0.95 & flag_hsv(:,:,1)<1)&flag_hsv(:,:,2)>0.16 & flag_hsv(:,:,3)>0.18));% 找出图像中红色的像素
[row, col] = ind2sub(size(flag_hsv),find( flag_hsv(:,:,3)<0.30));% 找出图像中黑色的像素
[row, col] = ind2sub(size(flag_hsv),find(flag_hsv(:,:,1)>0.11…
& flag_hsv(:,:,1)< 0.15 & flag_hsv(:,:,2)>0.16 & flag_hsv(:,:,3)>0.18));% 找出图像中黄色的像素
······

5.识别出指定的颜色区域
flag_hsv = rgb2hsv(flag); % 将图像的rgb色彩空间转化至hsv色彩空间     
flag_new = 255*ones(size(flag));% 创建一个白色图像,将特定颜色提取到此处
flag_new_hsv = rgb2hsv(flag_new);% 将该图像转至hsv色彩空间

[row, col] = ind2sub(size(flag_hsv),find( flag_hsv(:,:,3)<0.32));% 找出图像中绿色的像素
for i = 1 : length(row)
    flag_new_hsv(row(i),col(i),:) = flag_hsv(row(i),col(i),:);
end
flag_black = hsv2rgb(flag_new_hsv);

gray_black = rgb2gray(flag_black);
T = graythresh(gray_black); %得到一个阈值
bw_black = im2bw(gray_black, T); %转化为二值图像
dbw_black=imcomplement(bw_black);%二值图像取反

img_reg = regionprops(dbw_black,  'basic');
areas = [img_reg.Area];%各个区域的像素总数
rects = cat(1,  img_reg.BoundingBox);%各部分的最小矩形

figure(2),
imshow(flag);
for i = 1:size(rects, 1)     %获取行数
    rectangle('position', rects(i, :), 'EdgeColor', 'b');
end
text(0,0, 'black','color','blue','FontSize',16);

在这里插入图片描述

先将指定的颜色区域提取出来放到白色背景中;二值化处理后,颜色区域为黑,背景区域为白;再二值图像取反,颜色区域为白,背景区域为黑,那么此时连通区域即是颜色区域;用之前矩形框出连通区域的办法即可,只不过这个矩形框不显示在当前图片,而是显示在原图就可实现了。

6.设计GUI界面

进入:主页–>新建–>APP–>GUIDE
在这里插入图片描述
选择默认
在这里插入图片描述
例放置一个按钮,右键,查看回调,之后再对应的回调函数里写入函数即可;放置其他面板组件亦同理。
在这里插入图片描述
三、成果
这个设计最终完成的GUI界面如下:
在这里插入图片描述
其对应的回调函数文件链接在此

二值化处理功能:
在这里插入图片描述
提取黄色:
在这里插入图片描述

  • 31
    点赞
  • 181
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值