0

My original data is (640 x480 double ) 2D array and in this image (pixel data from camera) there are certain patterns or objects I want to detect with a specific size. I want to start from row 2 col 2 and increment in steps of 1 along the col and row to find pixels with certain value (i.e >1) this indicates a pixel which is potentially part of my object to be detected. If the adjacent pixels are equal 1 (minimum size of a object is a 3 x 3 array of 1s and maximum size of a object is a 100 x 100 array of 1s) then this is a potential object to be detected, for eg:

0 0 1 1 1 0 0
1 0 1 1 1 0 0
0 0 1 1 1 1 0 

In the above matrix 1 particle (3 x 3 array of 1s) is detected

Once I have found a particle I want to sum up all the element values which contribute to the particle.

I have started working on a simple matrix below see code but I have got lost once I have detected a particle I do not know how to change this back into my original double values in the original 2DArray called A.

Any help will be appreciated.

    A = magic(20);
    B = A>=300;
    pattern = [1,1];
    Cind = cell(1,20);
    Dind = cell(1,18);

    for r= 1:20

         Cind{r} = strfind(B(r,:),pattern);

    end

    for n= 1:18

         Dind{n} = isequal(Cind(1,n), Cind(1,n+1));

         if isempty(Cind{n})
            Dind{n}=0;
         end

     end
3
  • this might be of assistance, it isn't your exact problem, but, it uses cross-correlation to find the position of a template inside an image mathworks.com/help/signal/ref/xcorr2.html?refresh=true Commented Apr 24, 2015 at 16:30
  • Hi thanks but I do not have the signal processing tool box. I was hoping to solve this using the main Matlab program and no tool boxes. Commented Apr 28, 2015 at 7:35
  • Just to calrify. You are looking for a square block of 1's? like 3x3 block of 1's a 4x4 block of 1's or any SQUARE size all the way up to 100? Commented Apr 28, 2015 at 17:09

1 Answer 1

1

If you can't use any toolboxes then this solution will work. Here is a outline of what it does

  1. Goes through your entire search matrix (B) starting at 1,1 (upper left corner)
  2. creates a small subregion of B that is the same size as the pattern
  3. performs XOR on subregion and pattern, any pixels that are different get a value of 1, ow they are zero
  4. if the sum of all elements in the XOR == 0, then we have a match (no pixels were different)
  5. add the upper left cooordinates of the match to our output array

all coordinates are referenced with respect to upper left corner. so for instance

B=[0 1 0 0;
   0 1 1 1;
   0 1 1 1;
   0 1 0 1];
pattern = [1 1;
           1 1];

then the output is

 matching_regions =
     2     2
     2     3

meaning that the upper left corner of the match is located at (2,2). One thing to note though is that the matching regions can overlap. (2,3) also matches our pattern, but overlaps with the match at (2,2). I don't think this is an issue, but just something to note.

This function will work with any pattern that is smaller than the search region. Both the search region and the pattern must be logical arrays (only 0 and 1 or true and false)

A = magic(20);
B = A>=300; % this is a MxN array
[M,N] = size(B);

%% put your pattern here
%creates a 2,2 pattern of ones
pattern = ones(2,2);

%% do not change this code
[pat_r,pat_c] = size(pattern);

%this aray with old the upper left (row,column) of a pattern match
matching_regions = [];

%go over all rows without running off cells
for r = 1:1:M-pat_r+1
    %go over all cols without running off cells. since our search 
    %regions are square the limits are the same
   for c = 1:1:N-pat_c+1

       %grabs the pixels centered around (r,c) where r,c is the upper left
       %corner of the region
       search_region = B(r:r+pat_r-1, c:c+pat_c-1);

       %if all the pixels match
       if (nnz(xor(pattern, search_region)) == 0)
           %appends new row to table of matches
            matching_regions = [matching_regions; [r,c]];
       end
   end
end
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Andrew this is exactly what I was looking for to scan the rows and cols to detect a pattern. I think using the strfind was not a great idea as it creates a 1D array and getting back to 2D I think can not be done? Thanks for your help its appreciated. Kind regards Ranjit
Hi andrew is there a way of changing the rows and columns in matching_regions back to an array index? For example array A(1,1). The matching regions is an array of 2 cols and x rows but when you do C=A(matching_regions) it does not know that col 1 is the row index and col 2 is the col index. Thanks
I have worked this out, but there is probably a better way I have used: sub2ind function. I can get the values using MagicVals=A(sub2ind(sizeA),rows, cols)); where rows=matching_regions(:,1) and cols=matching_regions(1,:) there maybe an easier and more efficient way. Ranjit
actually, your way is great sub2ind is the way to go. But your columns might be wrong there is one coordinate per row. so if you did matching_regions(1) you would get (row,col) so if you want to seperate it into rows and column you say cols=matching_regions(:,2) where : means all rows and the 2 is for column 2. what you currently have says row 1 all columns which is the same as saying matching_region(1) also if this solved your problem can you mark it as the answer? just click the "Gray" checkmark and it will turn green. thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.