【问题标题】:How to draw a bounding box for a video in Matlab如何在 Matlab 中为视频绘制边界框
【发布时间】:2014-06-22 10:58:25
【问题描述】:

我有兴趣了解如何获取用于检测视频中的斑点的边界框。我的代码涉及背景减法,我使用的是简单的函数:

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

在此之后,我正在寻找可以在 blob 周围连续绘制边界框的代码。

【问题讨论】:

    标签: image matlab image-processing video-processing bounding-box


    【解决方案1】:

    如果你看一下BoundingBox属性的属性,有两个字段:

    • ul_corner - 表示边​​界框的左上角
    • width - 表示每个维度的宽度

    如果您正在处理单帧,这通常是一个 4 元素向量。因此,前两个元素为您提供图像左上角的(x,y) 坐标,而接下来的两个元素为您提供每个维度的宽度。

    假设你的 BoundingBox 属性给了你这个:

    [1 2 11 14]

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

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

    Ibox = reshape(Ibox, 4, length(Iprops))';
    

    因此,第 i 行将为您提供图像中第 i 个对象的边界框。

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

    imshow(fr);
    hold on;
    rectangle('Position', Ibox(1,:), 'EdgeColor', 'r');
    

    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
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 2017-07-17
      • 2020-01-27
      • 1970-01-01
      • 2012-10-11
      • 1970-01-01
      • 2021-12-04
      • 2021-05-28
      相关资源
      最近更新 更多