Search code examples
matlabimage-processingannotationsoverlapsubmatrix

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; the generated submatrices should be about the same size as the submatrices in X and contained in matrix M.

enter image description here

https://i.sstatic.net/UMIXk.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.


Solution

  • 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. For verification, let's see what other boxes fit these criteria for box 1, by doing - out3{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.