如何在自定义数据集上执行 RCNN 对象检测?

How to perform RCNN object detection on custom dataset?

我正在尝试使用 RCNN 在我自己的数据集上执行对象检测 the tutorial on Matlab webpage。基于下图:

我应该将图像路径放在第一列中,将每个对象的边界框放在后面的列中。但是在我的每幅图像中,每种对象都有不止一个。例如,一幅图像中有 20 辆车。我该如何处理?我应该为图像中的每个车辆实例创建单独的一行吗?

网站上的示例找到得分最高的像素邻域,并在图像中围绕该区域绘制边界框。当您现在有多个对象时,事情就会变得复杂。您可以使用两种方法来帮助查找多个对象。

  1. 找到得分超过某个全局阈值的所有边界框。
  2. 找到得分最高的边界框,并找到超过该阈值百分比的边界框。这个百分比是任意的,但根据经验和我在实践中看到的情况,人们倾向于选择图像中找到的最大分数的 80% 到 95% 之间。如果您将图像作为查询提交,其中包含未经分类器检测的训练对象,这当然会给您带来误报,但您将不得不在您的终端实现更多 post 处理逻辑。

另一种方法是选择一些值 k,然后您将显示与 k 最高分相关联的顶部 k 边界框。这当然需要你事先知道 k 的值是什么,并且它总是假设你已经像第二种方法一样在图像中找到了一个对象。


除了上述逻辑之外,您声明需要为图像中的每个车辆实例创建单独的行的方法是正确的。这意味着如果您在单个图像中有多个候选对象,则需要为每个实例引入一行,同时保持图像文件名相同。因此,例如,如果您在一张图像中有 20 辆车,则需要在文件名完全相同的 table 中创建 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;

最终结果将是图像中检测到的对象的多个边界框 - 每个检测到的对象一个注释。

我认为您实际上必须将该图像的所有坐标作为单个条目放入您的训练数据中 table。请参阅此 MATLAB tutorial for details. If you load the training data to your MATLAB locally and check the vehicleDataset variable, you will actually see this(抱歉,我的分数不够高,无法直接在我的答案中包含图像)。

总而言之,在您的训练数据 table 中,确保每张图片都有一个唯一的条目,并将任意多个边界框作为矩阵放入相应的类别中,其中每一行的格式为共 [x, y, width, height].