Image 如何在Matlab中绘制视频的边界框

Image 如何在Matlab中绘制视频的边界框,image,matlab,image-processing,video-processing,bounding-box,Image,Matlab,Image Processing,Video Processing,Bounding Box,我很想知道如何获得一个用于检测视频中斑点的边界框。我的代码涉及背景减法,我使用的是简单的函数: clc clear all close all m=0; n=0; readerobj = mmreader('dt2.wmv');% dt2 is my sample fixed cam video vidframes = read(readerobj); thresh = 15; bg = read(readerobj,1); bg_bw = double(rgb2gray(bg));

我很想知道如何获得一个用于检测视频中斑点的边界框。我的代码涉及背景减法,我使用的是简单的函数:

clc
clear all
close all

m=0; n=0;

readerobj = mmreader('dt2.wmv');% dt2 is my sample fixed cam video
vidframes = read(readerobj);

thresh = 15;

bg = read(readerobj,1);
bg_bw = double(rgb2gray(bg));

fr_size = size(vidframes);
width = fr_size(2);
height = fr_size(1);

fg = zeros(height, width);
numFrames=get(readerobj,'NumberofFrames');

for k = 1 : numFrames
    mov(k).cdata = vidframes(:,:,:,k);
    mov(k).colormap = [];
end

movie(mov, 1, readerobj.FrameRate)

a=1; x=[0 0]; p=0; c=0; 

for i = 2:2:numFrames
    fr = read(readerobj,i); 
    fg = zeros(size(fr));
    fr_bw = rgb2gray(fr);       
    fr_diff = abs(double(fr_bw) - double(bg_bw));  
    for j=1:width                 
      for k=1:height
         if ((fr_diff(k,j) > thresh))
             fg(k,j) = 255; %fr_bw(k,j)
         else
             fg(k,j) = 0;
         end
         if (fr_bw(k,j) > bg_bw(k,j))          
           bg_bw(k,j) = bg_bw(k,j) + 1;           
         elseif (fr_bw(k,j) < bg_bw(k,j))
           bg_bw(k,j) = bg_bw(k,j) - 1;     
         end
     end    

    %median filter to remove noise
    L=medfilt2(fg,[5,5]);            

    %removing small parts less than threshold area
    final=bwareaopen(L,4000);               

    %filling the holes
    ifill=imfill(final,'holes');          

    %to know the number of connected objects
    [Ilabel num]=bwlabel(ifill);          

    if (num>=1)
       %region properties of the image
       Iprops=regionprops(Ilabel);            
       %extracting the bounding box properties
       Ibox=[Iprops.BoundingBox]; 
    end
% ????? What do I do next?
end
clc
清除所有
全部关闭
m=0;n=0;
readerobj=mmreader('dt2.wmv');%dt2是我的固定摄像头视频示例
vidframes=读取(readerobj);
thresh=15;
bg=read(readerobj,1);
bg_bw=double(rgb2gray(bg));
fr_size=尺寸(视频帧);
宽度=fr_尺寸(2);
高度=fr_尺寸(1);
fg=零(高度、宽度);
numFrames=get(readerobj,'NumberofFrames');
对于k=1:numFrames
cdata=视频帧(:,:,:,k);
mov(k).colormap=[];
结束
电影(mov,1,readerobj.FrameRate)
a=1;x=[0];p=0;c=0;
对于i=2:2:numFrames
fr=读取(readerobj,i);
fg=零(尺寸(fr));
fr_bw=rgb2gray(fr);
fr_diff=abs(双倍(fr_bw)-双倍(bg_bw));
对于j=1:宽度
对于k=1:高度
if((fr_diff(k,j)>thresh))
fg(k,j)=255;%fr_bw(k,j)
其他的
fg(k,j)=0;
结束
如果(fr_bw(k,j)>bg_bw(k,j))
bg_bw(k,j)=bg_bw(k,j)+1;
elseif(fr_bw(k,j)=1)
%图像的区域属性
Iprops=区域支柱(Ilabel);
%提取边界框属性
Ibox=[Iprops.BoundingBox];
结束
% ????? 我下一步做什么?
结束

在此之后,我正在寻找一段代码,该代码将在blob周围连续绘制一个边界框。

如果您查看
边界框
属性的属性,则有两个字段:

  • ul_角
    -表示边界框的左上角
  • 宽度
    -表示每个尺寸中的宽度
如果处理单个帧,则通常为4个元素的向量。因此,前两个元素为您提供图像左上角的
(x,y)
坐标,而后两个元素为您提供每个维度的宽度

假设您的
BoundingBox
属性为您提供了以下信息:

[1 2 11 14]

这意味着左上角位于宽度为11、高度为14的
(x,y)=(1,2)
。请记住,
x
坐标从左到右水平延伸,而
y
坐标从上到下垂直延伸

当您最终获得这个
BoundingBox
属性时,如您的
Ibox=[Iprops.BoundingBox]所示语句,您可以使用
矩形
命令轻松地将边界框叠加到框架上。但是,请记住,
regionprops
函数可能返回多个区域。我不确定您的总体目标是什么,但是调用
Iprops.BoundingBox
并封装在括号内将返回作为单个向量的所有边界框属性。我建议将其重塑为
nx4
矩阵,如下所示:

Ibox = reshape(Ibox, 4, length(Iprops))';
因此,第i行将为您的图像中的第i个对象提供边界框

使用帧的
fr
变量,只需执行此操作(假设我们正在描绘图像中的第一个对象):

rectangle
命令接受2个参数(如果要修改其属性,还可以选择更多参数):您可以使用第一个参数指定是要常规矩形、圆角矩形还是椭圆,第二个参数指定矩形的尺寸。由于需要边界框,因此选择
Position
作为第一个参数,第二个参数是表示边界框左上角的4元素向量,后跟其宽度和高度

很方便,这是由
regionprops
结构中的
BoundingBox
属性给出的,因此您只需要在中替换
Ibox
。您可以指定您想要的盒子颜色。我选择了红色(
r
)让它脱颖而出

现在,如果您想连续显示每一帧的图像,只需显示每一幅图像,并每次调用
rectangle
函数即可

作为一个例子,让我们使用一个内置的MATLAB图像,并提取每个形状的相关边界框

BW = imread('text.png');
s  = regionprops(BW);
这是一个内置图像,包含一组文本。第二个MATLAB语句将尝试提取每个字符的所有相关边界框。
s
将返回一个88元素的结构。现在,让我们围绕它检测到的前三个字符绘制边界框:

b1 = s(1).BoundingBox;
b2 = s(2).BoundingBox;
b3 = s(3).BoundingBox;

imshow(BW);
hold on;
rectangle('Position', b1, 'EdgeColor', 'r');
rectangle('Position', b2, 'EdgeColor', 'g');
rectangle('Position', b3, 'EdgeColor', 'c');
。。。这就是我得到的。我已将一个边界框描绘为红色,一个为绿色,另一个为青色

如果要对单个帧自动执行此操作,请执行类似操作(假设您执行了我告诉过您的重塑)并将其放置在代码中问号所在的位置:

Ibox = reshape(Ibox, 4, length(Iprops))';
imshow(fr);
hold on;
for k = 1 : size(Ibox, 1)
   rectangle('Position', Ibox(k,:), 'EdgeColor', 'r');
end
希望这有帮助

Ibox = reshape(Ibox, 4, length(Iprops))';
imshow(fr);
hold on;
for k = 1 : size(Ibox, 1)
   rectangle('Position', Ibox(k,:), 'EdgeColor', 'r');
end