Simo Os
Simo Os

Reputation: 153

Extracting sub images of an image without repetitions using MATLAB

Given an image A, I want to subdivide it into blocks of a given size (let's say for example subimages of dimension 3-by-3) and remove repeated blocks. (Similar to what unique does to vectors, but for blocks.) I did try to use a loop as follows:

function [ Ref_M ] = Sub_Div_f( M,C_W )
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here
Sub_I=0;
Ref_M=0;
[L_M H_M ]=size(M); %deffine the size of d IMG
for i=1:C_W:L_M

    for j=1:C_W:H_M
        [L_Ref_M H_Ref_M ]=size(Ref_M);
        Sub_I=M(i:i+C_W-1,j:j+C_W-1);% Subimage
        if (i==1 && j==1)
           Ref_M=Sub_I;
        else
            nn=0;
            for k=1:C_W:H_Ref_M
                if ( Sub_I == Ref_M(1:C_W,k:k+C_W-1 ))
                    break;
                else
                    nn=nn+1;
                    if (nn==(H_Ref_M/C_W))
                       Ref_M(1:C_W, H_Ref_M+1:H_Ref_M+C_W)=Sub_I;
                    end
                end
            end       

        end
    end
end 

But that takes a lot of time. Can I use unique to get that? Like: S = unique(A,'3,3') or something. Or does unique work for single pixels only? If not using unique, is there are any function that can do that?

Upvotes: 0

Views: 324

Answers (1)

knedlsepp
knedlsepp

Reputation: 6084

First reshape all blocks of size blockSize=[3,3] to rows.

You can do this either using im2col if you have the image processing toolbox installed.

im2row = @(A,blockSize) im2col(A,blockSize,'distinct').';

or if you don't, you can use:

im2row = @(A,blockSize) ...
         reshape(permute(reshape(A, blockSize(1), size(A,1)/blockSize(1),...
                                    blockSize(2), size(A,2)/blockSize(2)),...
                         [2,4,1,3]),...
                 [], prod(blockSize));

Then we use unique(.,'rows') to filter out the unique blocks:

uniqueBlocks = unique(im2row(A,blockSize), 'rows');

You will then need to transpose and reshape the values back again to their block form:

reshape(uniqueBlocks.',blockSize(1),blockSize(2),[])

Upvotes: 1

Related Questions