Выбор подматриц случайным образом с учетом набора ограничений в MATLAB

Новичок в программировании здесь, и я действительно понятия не имею, как к этому подойти.

Моя проблема: у меня есть куча изображений, которые аннотированы прямоугольными ограничивающими рамками, и я хочу случайным образом выбрать другие прямоугольные ограничивающие рамки, которые не перекрываются с уже имеющимися ограничивающими рамками. Итак, в основном у меня есть матрица M и предопределенное подмножество X подматриц M, и я хочу сгенерировать новые подматрицы со случайными позициями, которые не перекрываются с X, но могут перекрываться друг с другом; сгенерированные подматрицы должны быть примерно того же размера, что и подматрицы в X и содержаться в матрице M.

введите здесь описание изображения

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

В приведенном выше примере прямоугольники на этом изображении представляют X, положительные примеры футбольных мячей; Я хочу сгенерировать равное количество коробок одинакового размера, которые не заключают в себе футбольные мячи, чтобы представить отрицательные примеры футбольных мячей.

Любое направление приветствуется, я делаю это в MATLAB.


person sakakak    schedule 22.05.2014    source источник
comment
У вас есть расположение пикселей, которые являются частью ограничивающих рамок? Или просто расположение пикселей в четырех углах коробок?   -  person Divakar    schedule 22.05.2014
comment
для каждой ограничивающей рамки у меня есть расположение пикселя в верхнем левом углу, а также ширина и высота bbox   -  person sakakak    schedule 22.05.2014


Ответы (2)


Давайте пройдемся по кодам и комментариям и попытаемся понять, как можно достичь цели, поставленной в вопросе.

%// 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}. Он выводит 3 и 4, что означает, что блоки 3 и 4 являются такими блоками для блока 1. Это можно проверить вручную, просмотрев значения в массиве ограничивающих блоков bb.

person Divakar    schedule 22.05.2014

Спасибо за помощь Дивакар.

Я также включил свое собственное решение для дальнейшего использования:

% 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
person sakakak    schedule 23.05.2014
comment
Кажется, это работает, верно!? Это была действительно интересная задача! - person Divakar; 23.05.2014