tags:

views:

81

answers:

1

Hey guys,

I could not figure out the last part of my research so if anyone could help me I would be really appreciated for the help.. :)

Say that my original matrix is,

X =

     0     0     0     0     0
     0     0    12     9     0
     0     4     9    15     0
     0    11    19     0     0
     0     2     4     8     0
     0     4     5     8     0
     0     0     0     0     0

and after finding the average of the non-zeros I will get something like below:

new_x =

     0         0           0           0         0 
     0         0       **9.0000**    9.0000      0 
     0      4.0000       9.0000    **9.0000**    0 
     0    **8.3333**   **8.0000**      0         0 
     0      2.0000       4.0000      8.0000      0 
     0      4.0000       5.0000      8.0000      0 
     0        0            0           0         0 

Note that any elements that are greater than 10 are the 'center' and we want to find the average of the non-zeros with the radius of say 1 m. where 1 meter = 1 element away from the center.

** ** means the center.

For this part I have used the following (from gnovice):

X=[0 0 0 0 0; 0 0 12  9 0; 0 4 9 15 0; 0 11 19 0 0;
   0 2 4 8 0; 0 4 5 8 0; 0 0 0 0 0];
kernel=[0 1 0; 1 0 1; 0 1 0];
sumx=conv2(X,kernel,'same');
nx=conv2(double(X>0),kernel,'same');
index=(X>10);
new_x=X;
new_x(index)=sumx(index)./max(nx(index),1);

So my question is that I want to compare the neighbor elements with its center whether they are equal, lesser, or greater. If it is greater or equal then '1' or else '0'.Also whatever elements that are outside the radius can be ignored and replaced with '0'.

For example, the 9 in the middle is within the radius of 12, 15, and 19 centers, so take the minimum center of those `min[9.000, 9.000, 8.000] = 8.000. In this case 4 will not take into the consideration as it is not called the 'center' as well as [ 8 4 5 and 8 ] in the last two rows.

So I want something like below:

Test_x =

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

I have put this first part in the forum before and I am really appreciated for every suggestion earlier.

Please give me some ideas to start with. I have tried using a loop but it didnt seem to work very well. Any MATLAB function that can do the job for me..

Thank you so much for the help.

Beginner at MATLAB


I think I found the solution for this question by using Jonas techniques. Thank you for the help Jonas and gnovie:)

X=[0 0 0 0 0; 0 0 12 9 0; 0 4 9 15 0; 0 11 19 0 0; 0 2 4 8 0; 0 4 5 8 0; 0 0 0 0 0];

kernel=[0 1 0; 1 0 1; 0 1 0];

sumx=conv2(X,kernel,'same');

nx=conv2(double(X>0),kernel,'same');

avg_x=X;

avg_x(avg_x<10)=0;

index=(avg_x>10);

avg_x(index)=sumx(index)./max(nx(index),1);

avg_x =

     0         0         0         0         0
     0         0    9.0000         0         0
     0         0         0    9.0000         0
     0    8.3333    8.0000         0         0
     0         0         0         0         0
     0         0         0         0         0
     0         0         0         0         0

tmp_x=avg_x;

maxVal=max(avg_x(:))+1;

tmp_x(tmp_x==0)=maxVal;

tmp_x=imerode(tmp_x,kernel);

Test_x=X>=tmp_x;

+1  A: 

I think what you want to do is create a new array based on new_x that replaces every element by the minimum of its 4-connected neighbours. Then you can compare the new array to new_x.

Here's a way to do this (requires the image processing toolbox)

tmp_x = new_x;
maxVal = max(new_x(:))+1;
tmp_x(tmp_x == 0) = maxVal; %# replace all the zeros in tmp_x with something large
tmp_x = imerode(tmp_x,kernel); %# kernel is the same as in the OP
Test_x = new_x >= tmp_x; %# put ones wherever the value is
                         %# greater or equal the neighbour's minimum 
%# only keep 1's that are next to 'centers'
Test_x = Test_x .* imdilate(X>10,strel('disk',1))

Test_x =
     0     0     0     0     0
     0     0     1     1     0
     0     0     1     1     0
     0     1     1     0     0
     0     0     1     0     0
     0     0     0     0     0
     0     0     0     0     0

Note that I get one more ones with this logic than you do.

Jonas
Thank you for your help.However what I want to do is to compare the neigbors with its centers. As you can see the center will have ** **, shown in new_x.Also whatever elements that are outside the radius of the center, you can ignore them and put them to zero.
Nadhris
@Nadhris: I added a line so that only those elements are considered that are within one step from at least one of the centers. Also, if you find that an answer is useful for you, please consider accepting and/or upvoting it.
Jonas
Your answer is really close to what I am looking for. But it should not be 1 at (5,3) because the value 4 is less than the center 8.
Nadhris

related questions