简体   繁体   English

在MATLAB中给定约束条件的情况下随机选择子矩阵

[英]Selecting submatrices at random given a set of constraints in MATLAB

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; 因此,基本上,我有一个矩阵M和一个M子矩阵的预定义子集X,我想生成具有不与X重叠但可以相互重叠的随机位置的新子矩阵。 the generated submatrices should be about the same size as the submatrices in X and contained in matrix M. 生成的子矩阵的大小应与X中的子矩阵大小相同,并包含在矩阵M中。

在此处输入图片说明

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

In the example above, the boxes in that image represent X, positive exambles of soccer balls; 在上面的示例中,该图像中的方框表示X,即足球的正序; 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. 任何方向都值得赞赏,我正在MATLAB中进行此操作。

Let us go through the codes and comments and try to understand how the target set in the question could be achieved. 让我们仔细阅读代码和注释,并尝试了解如何实现问题中设定的目标。

%// 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)

How to use the code - 如何使用代码-

out3 is the final output that houses the final decision for each box, what other boxes are similar and not overlapping. out3是容纳每个框的最终决策的最终输出,还有哪些其他框相似且不重叠。 For verification, let's see what other boxes fit these criteria for box 1, by doing - out3{1} . 为了进行验证,让我们通过执行out3{1}查看其他哪些框符合框1的这些条件。 It prints out 3 and 4 , meaning box 3 and 4 are such boxes for box 1. This could be manually verified by looking at the values in the bounding box array bb . 它打印出34 ,这意味着框3和4就是框1的框。这可以通过查看边界框bb中的值来手动验证。

Thanks for your help Divakar. 感谢您的帮助Divakar。

I have also included my own solution for future reference: 我还提供了自己的解决方案,以供将来参考:

% 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM