0

我有興趣瞭解如何獲取用於檢測視頻中的斑點的邊界框。我的代碼涉及背景減除,我使用簡單功能:如何在Matlab中繪製視頻的邊界框

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 

在此之後,我要尋找的代碼,會不斷周圍畫團塊邊界框。

回答

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並在括號內封裝將返回所有作爲單個向量您的邊界框屬性。我會建議重新塑造它,以便它是一個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'); 

...這就是我所得到的。我已經勾畫出一個邊框爲紅色,一個爲綠色,另一個爲青色。

enter image description here

如果你想針對單一幀自動完成這個,做這樣的事情(假設你重塑我告訴你)地方這其中問號是在你的代碼:

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

希望這會有所幫助!