1

New to programming here and I really have no idea how to approach this.

My problem: I have a bunch of images that are annotated with rectangular bounding boxes and want to pick other rectangular bounding boxes at random that do not overlap with the bounding boxes I already have. So basically I have a matrix M and a predefined subset X of submatrices of M and I want to generate new submatrices with random positions that do not overlap with X but can overlap with each other; the generated submatrices should be about the same size as the submatrices in X and contained in matrix M.

enter image description here

http://i.imgur.com/74AEI2x.png

In the example above, the boxes in that image represent X, positive exambles of soccer balls; I want to generate an equal number of boxes of the same size that do not enclose soccer balls, to represent negative examples of soccer balls.

Any direction is appreciated, I'm doing this in MATLAB.

4

2 回答 2

1

让我们浏览一下代码和注释,并尝试了解如何实现问题中设定的目标。

%// Bounding box array, where the first and second columns denote the X-Y 
%// location of the uppper-left corner pixel. The third and fourth columns
%// denote the extent of the repctive boxes along X and Y directions 
%// respectively. Some random values are used here for demo purposes.
bb = [
    12 10 10 5
    15 20 14 12
    135 60 11 4
    20 30 10 7
    20 30 13 13
    20 30 13 14]

%// Tolerance in terms of the size difference betwen similar boxes that
%// is admissible as a less than or equal to value
tol = 2

%// Get X and Y direction limits for each box
xlims = [bb(:,1) bb(:,1) + bb(:,3)]
ylims = [bb(:,2) bb(:,2) + bb(:,4)];

%// Create a binary matrix that decides whether each box is in or out with
%// respect to all other boxes along both X and Y directions. Ones mean "in"
%// and zeros denote "out".
x1 = bsxfun(@ge,xlims(:,1),xlims(:,1)') & bsxfun(@le,xlims(:,1),xlims(:,2)')
x2 = bsxfun(@ge,xlims(:,2),xlims(:,1)') & bsxfun(@le,xlims(:,2),xlims(:,2)')
x12 = x1 | x2;

y1 = bsxfun(@ge,ylims(:,1),ylims(:,1)') & bsxfun(@le,ylims(:,1),ylims(:,2)')
y2 = bsxfun(@ge,ylims(:,2),ylims(:,1)') & bsxfun(@le,ylims(:,2),ylims(:,2)')
y12 = y1 | y2;

d1 = x12 & y12

%// Create another binary matrix based on sizes to decide for each box
%// what other boxes are "similar"
szmat = bb(:,[3 4])
v1 = abs(bsxfun(@minus,szmat,permute(szmat,[3 2 1])));
szmat_d = squeeze(all(v1<=tol,2));

%// Get a binary matrix based on combined decisions from X-Y incompatibility
%// and sizes. Please note for incompatibility, negation of d1 is needed.
out1 = ~d1 & szmat_d
out1(1:size(out1,1)+1:end)=0
out2 = mat2cell(out1,ones(1,size(out1,1)),size(out1,2))
out3 = cellfun(@find,out2,'uni',0)

如何使用代码 -

out3是包含每个框的最终决定的最终输出,其他框相似且不重叠。为了验证,让我们看看还有哪些其他框符合框 1 的这些标准,方法是 - out3{1}。它打印出34,意思是框 3 和 4 是框 1 的框。这可以通过查看边界框数组中的值来手动验证bb

于 2014-05-22T20:18:19.960 回答
1

感谢您的帮助迪瓦卡。

我还包括了我自己的解决方案以供将来参考:

% Loop through each image in the dataset
for i=1:numel(anno.image_names)

% Skip images with no positive examples
inds = anno.bboxes(:,1) == i;
if sum(inds) == 0
    continue
end

% Read image
img = imread(fullfile(folder,anno.image_names{i}));

% Query image size
w_img = size(img,2);
h_img = size(img,1);

% Define the size of new negative bboxes to be the mean of the size of
% all positive bboxes in the image
w_new = floor(mean(anno.bboxes(inds,5)));
h_new = floor(mean(anno.bboxes(inds,6)));

% Define top-left and bottom-right corner of each existing bbox
tmp_bboxes = anno.bboxes(inds,:);
x = floor(tmp_bboxes(:,3));
y = floor(tmp_bboxes(:,4));
x_max = ceil(tmp_bboxes(:,3)+tmp_bboxes(:,5));
y_max = ceil(tmp_bboxes(:,4)+tmp_bboxes(:,6));

% Choose a random origin (a,b) that represents the upper-left
% corner pixel location and is properly constrained by the image size
a = randi([1,w_img - w_new],[sum(inds), 1]);
b = randi([1,h_img - h_new],[sum(inds),1]);

% Check if for the origin (a,b), the bbox created by the origin and
% w_new, h_new overlaps with the positive bboxes
inds2 = (a<x & (a+w_new)<x) | (a>x_max & (a+w_new)>x_max) | ...
    (b<y & (b+h_new)<y) | (b>y_max & (b+h_new)>y_max);
while sum(inds2) < sum(inds)
    a(~inds2) = randi([1,w_img - w_new],[sum(~inds2), 1]);
    b(~inds2) = randi([1,h_img - h_new],[sum(~inds2),1]);
    inds2 = (a<x & (a+w_new)<x) | (a>x_max & (a+w_new)>x_max) | ...
    (b<y & (b+h_new)<y) | (b>y_max & (b+h_new)>y_max);
end

end
于 2014-05-23T02:21:01.627 回答