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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在自定义数据集上执行RCNN对象检测?相关的知识,希望对你有一定的参考价值。

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

enter image description here

我应该在下面的列中将图像路径放在第一列和每个对象的边界框中。但在我的每个图像中,每种图像都有多个对象。例如,一张图像中有20辆车。我应该怎么处理?我应该为图像中的每个车辆实例创建一个单独的行吗?

答案

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

  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)

这仅适用于分数最高的一个对象。如果要对多个对象执行此操作,则可以使用从score方法输出的detect,并找到适应情境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;

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

另一答案

我认为你实际上必须将该图像的所有坐标作为训练数据表中的单个条目。有关详细信息,请参阅此MATLAB tutorial。如果您在本地将训练数据加载到MATLAB并检查vehicleDataset变量,您实际上会看到this(对不起,我的分数不够高,不能直接在我的答案中包含图像)。

总而言之,在训练数据表中,确保每个图像都有一个唯一的条目,然后将许多边界框作为矩阵放入相应的类别中,其中每一行的格式为[x, y, width, height]

以上是关于如何在自定义数据集上执行RCNN对象检测?的主要内容,如果未能解决你的问题,请参考以下文章

如何将使用 Mask Rcnn 在自定义对象检测上创建蒙版图像的 Keras 模型转换为 CoreML 模型以在 iOS 应用程序中使用?

在自定义数据集上使用 roboflow 对象检测 Yolov4 pytorch 模型时出现值错误

YOLOv8已至,精度大涨!教你如何在自定义数据集上训练它

如何在 tensorflow 对象检测 API 中使用“忽略”类?

如何从 RCNN 中裁剪分割的对象?

Tensorboard mAP 分数都是 0,即使 loss 很低