(1)在编写摄像头采集图像程序,能够对图像进行采集、保存处理;
(2)对采集图像进行预处理,RGB 到 YCBCR 的色彩空间转换,用各个通道的阈值对图像进行二值化;形态学处理:腐蚀、膨胀、孔洞填充,连通区域提取,识别出指定的颜色区域;
(3)能够识别到多个颜色并进行分割;
(4)设计 GUI 界面,能够通过界面进行图像采集、识别、输出信息。
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');
用于获取采集到的视频
OBJ = videoinput(adaptorname,deviceID,format)
adaptorname:适配器名称
deviceID:设备ID
format:视频格式
命令行输入imaqhwinfo可获取相机的适配器名称,输入
win_info = imaqhwinfo(‘winvideo’) %适配器名称随上步查询结果变动
可查询设备ID(通常如果是笔记本的话会出现两个ID,通常相机的设备ID是2)
输入win_info.DeviceInfo.SupportedFormats可查询相机支持的编码格式
用于在视频中捕捉得到一个图片
用于显示图片,通常与figure搭配使用
例:figure,imshow(I)%创建一个新的窗口显示图片
用于创建一个新的文件夹,绝对路径和相对路径都可
用于保存图片
imwrite(a,filename,format)
a:图片名称
filename:保存路径
format:保存的格式
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);
用于读入将被处理的图片
obj=imread(filename.fmt);
2其实就是to,该函数用于将RGB图片转换为YCBCR图片
那为什么要转换为YCbCr图片呢?
用于压缩图片!因为人的眼睛对YCbCr色彩空间编码的视频中的Y分量更加敏感,而Cb和Cr的微小变化不会引起视觉的不同。因此我们可以通过对Cb和Cr分子进行采样来减小图像的数据量,使得图像对于储存需求和传输带宽的要求大大降低,从而达到在完成图像压缩的同时也保证视觉上几乎没有损失。
其中,Y(Luminance):明亮度和浓度
Cb(Chrominance-Blue):颜色中的蓝色浓度偏移量
Cr(Chrominance-Red):颜色中的红色浓度偏移量
根据各个通道的阈值进行二值化
%进行形态学处理:腐蚀、膨胀、孔洞填充
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
即用来度量图像区域属性的函数,其属性包括: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’);%计算全部属性
用于串联数组或矩阵,并且串联的数组或矩阵的维度要一致
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
figure; %创建一个新的窗口
figure(2);%窗口的命名为2,且窗口的命名不可以是0
figure(‘name’,‘show’);%窗口命名为show
用于获取矩阵的行数和列数
<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的列数
用于创建二维矩阵对象
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’表示面内填充颜色为绿色。
【此算法来自这位大神: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));% 找出图像中黄色的像素
······
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);
先将指定的颜色区域提取出来放到白色背景中;二值化处理后,颜色区域为黑,背景区域为白;再二值图像取反,颜色区域为白,背景区域为黑,那么此时连通区域即是颜色区域;用之前矩形框出连通区域的办法即可,只不过这个矩形框不显示在当前图片,而是显示在原图就可实现了。
进入:主页–>新建–>APP–>GUIDE
选择默认
例放置一个按钮,右键,查看回调,之后再对应的回调函数里写入函数即可;放置其他面板组件亦同理。
三、成果
这个设计最终完成的GUI界面如下:
其对应的回调函数文件链接在此