2

我試圖用RCNN在我自己的數據集the tutorial on Matlab webpage之後執行對象檢測。基於下面的圖片:如何在自定義數據集上執行RCNN對象檢測?

enter image description here

我應該把圖像路徑在第一列和每個對象在以下幾列的邊框。但是在我的每張圖片中,每種類型都有不止一個對象。例如,一幅圖像中有20輛車。我應該如何處理?我應該爲圖像中的每個車輛實例創建一個單獨的行嗎?

回答

2

在網站上找到的示例找到最大分數的像素鄰域,並在圖像中該區域周圍繪製邊界框。當你有多個對象時,這會使事情變得複雜。有兩種方法可以用來幫助查找多個對象。

  1. 找到超過某個全局閾值的分數的所有邊界框。
  2. 找到最大分數的邊界框並找到超過此閾值百分比的邊界框。這個比例是任意的,但從經驗和我在實踐中看到的情況來看,人們傾向於選擇圖像中最大得分的80%到95%。這當然會給你帶來誤報,如果你提交一個圖像作爲查詢與對象未經過訓練的分類器檢測到,但你將不得不在你的一端實施一些更多的後處理邏輯。

另一種方法是選擇一些價值k,你會顯示與k得分最高相關頂部k包圍盒。這當然要求您事先知道k的價值,它總是會假定您已經像第二種方法那樣在圖像中找到了一個對象。


除了上述邏輯,你陳述在需要創建一個單獨的行的圖像在車輛的每個實例的方法是正確的。這意味着如果在單個圖像中有多個候選對象,則需要爲每個實例引入一行,同時保持圖像文件名相同。因此,如果您在一個圖像中有20輛車,則需要在表中創建20行,其中文件名全都相同,並且您將爲該圖像中的每個不同對象指定單個邊界框。

一旦你做到了這一點,假設你已經訓練了R-CNN探測器和你想使用它,原來的代碼來檢測對象是以下引用的網站:

% Read test image 
testImage = imread('stopSignTest.jpg'); 

% Detect stop signs 
[bboxes, score, label] = detect(rcnn, testImage, 'MiniBatchSize', 128) 

% Display the detection results 
[score, idx] = max(score); 

bbox = bboxes(idx, :); 
annotation = sprintf('%s: (Confidence = %f)', label(idx), score); 

outputImage = insertObjectAnnotation(testImage, 'rectangle', bbox, annotation); 

figure 
imshow(outputImage) 

這隻適用於具有最高分數的一個對象。如果您想爲多個對象執行此操作,則可以使用從detect方法輸出的score,並找到適合情況1或情況2的位置。

如果您有情況1,則將其修改爲看起來像以下。

% Read test image 
testImage = imread('stopSignTest.jpg'); 

% Detect stop signs 
[bboxes, score, label] = detect(rcnn, testImage, 'MiniBatchSize', 128) 

% New - Find those bounding boxes that surpassed a threshold 
T = 0.7; % Define threshold here 
idx = score >= T; 

% Retrieve those scores that surpassed the threshold 
s = score(idx); 

% Do the same for the labels as well 
lbl = label(idx); 

bbox = bboxes(idx, :); % This logic doesn't change 

% New - Loop through each box and print out its confidence on the image 
outputImage = testImage; % Make a copy of the test image to write to 
for ii = 1 : size(bbox, 1) 
    annotation = sprintf('%s: (Confidence = %f)', lbl(ii), s(ii)); % Change  
    outputImage = insertObjectAnnotation(outputImage, 'rectangle', bbox(ii,:), annotation); % New - Choose the right box 
end 

figure 
imshow(outputImage) 

注意,而超過了閾值不同的變量的情況下的那些的子集,要在兩者之間交叉引用,我已經保存了原有的邊界框,標籤和成績在原來的變量。如果您想要適應情況2,代碼與情況1保持一致,但定義閾值除外。

從代碼:

% New - Find those bounding boxes that surpassed a threshold 
T = 0.7; % Define threshold here 
idx = scores >= T; 
% [score, idx] = max(score); 

...現在將變爲:

% New - Find those bounding boxes that surpassed a threshold 
perc = 0.85; % 85% of the maximum threshold 
T = perc * max(score); % Define threshold here 
idx = score >= T; 

最終的結果將是檢測對象的多個邊界框的形象 - 一個每個檢測到的對象的註釋。

+1

謝謝您的完整回覆。這非常有幫助。我只是有一個關於表現的問題。如果閾值對某些圖像不是最好的會發生什麼?這會導致錯過一些物體並使它們不被發現? –

+0

@HadiGhahremanNezhad這是正確的。閾值純粹是實驗性的。您必須查看您擁有的圖像種類以及您擁有的物體,並運行多個具有不同閾值的試驗。然後,您會選擇導致最高精度和召回率的閾值。 – rayryeng

+0

謝謝你的提示真的很棒。但是這仍然很棘手,因爲我有** 11 **類型的對象,並且在單個圖像中可能有多個對象。所以創建數據單元並不容易,我很困惑它應該爲每個圖像分配多少行。我已經在深度學習中尋找了一個合適的物體檢測工具,但還沒有找到一個簡單的工具。我嘗試**咖啡**,** Nvidia數字**和現在的matlab,沒有運氣呢!他們都沒有爲我工作。 –

1

我認爲你實際上必須把這個圖像的所有座標作爲你的訓練數據表中的一個條目。有關詳細信息,請參見此MATLAB tutorial。如果您將訓練數據加載到您的MATLAB本地並檢查vehicleDataset變量,您實際上會看到this(對不起,我的分數不夠高,無法直接在我的答案中包含圖像)。總之,在你的訓練數據表中,確保每個圖像都有一個唯一的條目,然後將許多邊界框作爲矩陣放入相應的類別中,其中每行的格式爲[x, y, width, height]

+0

基於你放置的圖片,這意味着,例如,如果我在一個圖像中有5輛車,我應該將所有邊界框信息放在一行中,並用';'分隔。這是正確的嗎? –

+1

@HadiGhahremanNezhad是的,但在MATLAB中,';'會被解釋爲矩陣的新行。所以你實際上是創建一個多行矩陣,每一行都是一個邊界框。 –

相關問題