Matlab 自动获取图片中已经框好的所有矩形的左上角坐标和宽高

整体效果如下:

坐标信息和矩形宽高放在txt文件中:

 

整体思路如下:

1:因为图中的矩形框是用不同颜色框出来的,我们可以把每一个颜色的所有矩形框提取出来,变成二值图像(只有黑色和白             色)。求出此颜色的每个矩形的信息。

2:如果按颜色分出来的矩形框只有一个,就可以用[x,y]=find(BW==1); (BW:为提出来的二值图像   find(BW==1):寻找二值                    图像中白色的区域(1为白色,0为黑色))把x,y的坐标都求出来,此时min(x),min(y)Matlab可以自动求出。

3:如果按颜色分出来的矩形有多个,此时就不知道每个矩形的最小最大的xy值了。

     用 L = bwlabel(colorb); (bwlabel:标识所有黑色背景下白色连通区域 (连通区域:封闭的区域) colorb:二值图片)

         num = max(max(L)); (计算有多少个连通区域

        这两句语句,把此时图片的中的每个矩形变成一个一个的单独矩形了,此时用循环用此语句

         [x,y] = find(L == i);  (i代表第几个连通区) 

4:建立一个矩阵存放这些信息,在把这些信息放到txt文件中(如果不建立矩阵,存放到txt文件中的内容将都会在第一行第一             列中

分步讲解 :

主函数:

1:

rgb=imread('61.jpg');  % 读取图片
figure,imshow(rgb);    %显示图片   figure:弹出窗口
r = rgb(:,:,1);               %提取彩色图像的红色分量。
g = rgb(:,:,2);              %提取彩色图像的绿色分量。
b = rgb(:,:,3);              %提取彩色图像的蓝色分量。
 

2:

符合红色,蓝色,绿色,橘红色和紫色的rgb值挑选出来赋给变量red,blue,green,orange,purple 3

red=r>=175&g<36&b<36;        
blue=r<=60&g<135&b>70;
green=(20>r)&(g>80)&(g<100)&(b>20)&(b<=35);
orange=(r>200)&(g<118)&(g>36)&b<50;
purple=(175>r)&(r>97)&g<35&(b>52)&(b<=67);
 

3:

把每一个颜色放到一个数组中,为了方便循环调用shibie()函数(后面讲解)减少代码的冗余。

a{1}=red;     此时取到的就是二值图像
a{2}=blue;
a{3}=green;
a{4}=orange;
a{5}=purple;

4:

循环调用shibe()函数

yz=300;        %作为bwareaopen函数的参数
for i=1:5
    if i==1
        str='red';
    elseif i==2
        str='blue';
    elseif i==3
        str='green';
    elseif i==4
        str='orange';
    elseif i==5
        str='purple';
    end
                
    shibie(a{i},yz,str)
end

子函数:

1:

function [ ]  = shibie(color,yz,str)
 
       colorb = bwareaopen(color,yz);   %删除二值图像BW中面积小于P对象  去除杂点!yz:300(主函数传进的参数)就是把二值图像color中像素比300小的都删除了

2:

如果一个颜色中有好多矩形,但是这些矩形有重叠的用颜色把他们分开后,有的矩形显示不完整,可能会出现中间有间断

的情况,此时进行连通区域划分时候会不准,所以在此之前要对图中的矩形进行扩充线条(膨胀)

      connect_size = 8;
       se = strel('disk',connect_size);
       colorb = imdilate(colorb,se);
       figure;imshow(colorb);
        title('扩充线条');

3:

  使图片进行连通区域的划分

      L = bwlabel(colorb); 
       num = max(max(L));

4:

创建一个cell数组(cell数组可以装数字和字符 都可以的)

 B=cell(num,5);

5:

循环计每个颜色中连通区域中矩形的坐标

for i = 1:num
    [x,y] = find(L == i); 
    minx=min(y);
    maxx=max(y);
    miny=min(x);
    maxy=max(x);
    Width=maxx-minx;
    Hight=maxy-miny;
   
         B{i,1}=str;
         B{i,2}=minx;
         B{i,3}=miny;
         B{i,4}=Width;
         B{i,5}=Hight;
end

6:

把每个连通区域中矩形坐标信息放在txt文件中

fid=fopen('sun9.txt','a');    
 [m,n]=size(B);
for h=1:1:m
     fprintf(fid,'%s%d:\t ',B{h,1},h); 
    for j=2:1:n
        if j==n          
            fprintf(fid,'%g\r\n',B{h,j});
        else           
            fprintf(fid,'%g\t',B{h,j});
        end
    end
end

整体代码:

主函数

rgb=imread('61.jpg');  % 读取图片
figure,imshow(rgb);    %显示图片   figure:弹出窗口
r = rgb(:,:,1);               %提取彩色图像的红色分量。
g = rgb(:,:,2);              %提取彩色图像的绿色分量。
b = rgb(:,:,3);              %提取彩色图像的蓝色分量。


red=r>=175&g<36&b<36;
blue=r<=60&g<135&b>70;
green=(20>r)&(g>80)&(g<100)&(b>20)&(b<=35);
orange=(r>200)&(g<118)&(g>36)&b<50;
purple=(175>r)&(r>97)&g<35&(b>52)&(b<=67);
a{1}=red;
a{2}=blue;
a{3}=green;
a{4}=orange;
a{5}=purple;
figure;
yz=300;   %作为bwareaopen函数的参数
for i=1:5
    if i==1
        str='red';
    elseif i==2
        str='blue';
    elseif i==3
        str='green';
    elseif i==4
        str='orange';
    elseif i==5
        str='purple';
    end
                
    shibie(a{i},yz,str)
end
    

子函数

function [ ]  = shibie(color,yz,str)
 figure()
   imshow(color);
    
       colorb = bwareaopen(color,yz);  %删除二值图像BW中面积小于P对象 
       
       connect_size = 8;
       se = strel('disk',connect_size);
       colorb = imdilate(colorb,se);
       figure;imshow(colorb);
        title('扩充线条');
        
       L = bwlabel(colorb); 
       num = max(max(L));
       
       B=cell(num,5);
for i = 1:num
    [x,y] = find(L == i); 
    minx=min(y);
    maxx=max(y);
    miny=min(x);
    maxy=max(x);
    Width=maxx-minx;
    Hight=maxy-miny;
   
         B{i,1}=str;
         B{i,2}=minx;
         B{i,3}=miny;
         B{i,4}=Width;
         B{i,5}=Hight;
end

 fid=fopen('sun9.txt','a');    
 [m,n]=size(B);
for h=1:1:m
     fprintf(fid,'%s%d:\t ',B{h,1},h); 
    for j=2:1:n
        if j==n          
            fprintf(fid,'%g\r\n',B{h,j});
        else           
            fprintf(fid,'%g\t',B{h,j});
        end
    end
end

end

测试获取的点时候时候正确

采用的方法是:用已经获取的坐标在原来带有矩形的图像上画矩形,查看时候能和原来的矩形重合。

思路:1:读取图片

          2:读取存放坐标的txt

           3:在原图上矩形(用plot()函数) 

img = imread('61.jpg');
filename='sun9.txt';
[data1,data2,data3,data4,data5]=textread(filename,'%s%f%f%f%f',18);

   figure;
   hold on;
   imshow(img);
   hold off
   for i=1:12
       width = data4(i);
       hight = data5(i);
       x1 = data2(i) ;
       x2 = x1 + width;
       y1 =data3(i);
       y2 = y1 + hight;
       hold on;
      rectx = [x1 x2 x2 x1 x1];
      recty = [y1 y1 y2 y2 y1];
      plot(rectx, recty, 'linewidth',2);
   hold off;
   end
   
 

方法二:用鼠标点击获取点信息

函数:

ginput 提供了一个十字光标使我们能更精确的选择我们所需要的位置,并返回坐标值。函数调用形式为:

[x,y] = ginput(n),能使你从当前的坐标系中读取n个点,返回这n个点的x,y坐标,均为nX1的向量。可以按回车提前结束读数。
[x,y] = ginput 可以无限的读取坐标直到按下回车键。

clc,clear,clear all
image = imread('61.jpg');
figure ,imshow(image)

data = [ ];
image_array = [1,2,3,4,5,6,7,8];
image_array_length = length(image_array);
for i = 1:image_array_length
    [x, y] = ginput(2);
    width = abs(x(2) - x(1));
    height = abs(y(2) -y(1));
    data = [data; image_array(i), x(1), y(1), width, height];
end

用到的函数 

connect_size = 8;
 se = strel('disk',connect_size);
 colorb = imdilate(colorb,se);

strel()

具体用法:SE = strel(shape,parameters)
创建由指定形状shape对应的结构元素。其中shape的种类有
arbitrary'
'pair'
'diamond'
'periodicline'
'disk'
'rectangle'
'line'
'square'
'octagon
参数parameters一般控制SE的大小。

imdilate()

imdilate函数用于对图像实现膨胀操作。(形态学)

img=imdilate(img,SE) 。参数SE为由strel函数返回的结构元素或者结构元素对象组。

bwareaopen()

功能: 用于从对象中移除小对象。   
用法: BW2 = bwareaopen(BW,P)
           BW2 = bwareaopen(BW,P,CONN)   从二值图像 中移除所有小于P的连通对象。CONN对应邻域方法,默认为8。

 yz=300;

colorb = bwareaopen(color,yz);

bwlabel()

bwlabel功能:对连通对象进行标注,bwlabel主要对二维二值图像中各个分离部分进行标注.

L = bwlabel(BW,n) :返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。

 L = bwlabel(colorb); 

textread()

实际应用中经常要读取txt文件,这个时候就需要用到强大的textread函数。
它的基本语法是:
[A,B,C,...] = textread(filename,format)
[A,B,C,...] = textread(filename,format,N)
其中filename就是文件名 format就是要读取的格式A,B,C就是从文件中读取到的数据
中括号里面变量的个数必须和format中定义的个数相同。 如果每N行相同格式的数据,可采用[A,B,C,...] = textread(filename,format,N)的语法,读取N次。

[data1,data2,data3,data4,data5]=textread(filename,'%s%f%f%f%f',18);

ginput ()

ginput提供了一个十字光标使我们能更精确的选择我们所需要的位置,并返回坐标值。函数调用形式为:

[x,y] = ginput(n),能使你从当前的坐标系中读取n个点,返回这n个点的x,y坐标,均为nX1的向量。可以按回车提前结束读数。
[x,y] = ginput 可以无限的读取坐标直到按下回车键。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值