Asked by David
on 9 May 2013

I have a three dimensional matrix of size (i,j,k). This matrix is composed of values ranging from 0 to 255. I am interested in identifying those elements that have a value of zero AND whose neighbors are also all zero. I then want to change the value of those elements that meet this criteria. I have thought of three incomplete solutions.

1) Find all the elements that meet this criteria and store their indexes and then change their values (see below). This doesn't really seem like a viable solution though. Without being able to pre-allocate the size of variable *inde* this chunk of code becomes painfully slow. I also think there should be a better way to do this than raping my code with *for* loops. (I should point out, I have already discovered what happens if you change the element value within the nested *for* loops)

count=0; for k=1:z; for j=1:y; for i=1:x; if (k~=1 && j~=1 && i~=1 && k~=z && j~=y && i~=x) if m(i,j,k)==0 && m(i+1,j,k)==0 && m(i-1,j,k)==0 && ... (i,j+1,k)==0 && m(i,j-1,k)==0 && m(i,j,k-1)==0 && ... (i,j,k+1)==0; count=count+1; inde(count,:)= [i j k]; end end end end end m(inde(:,1),inde(:,2),inde(:,3))=1;

2)I thought about using the find function, but that tends to get me nowhere other than knowing where all the zeros are.

IND=find(m==0); s=[x,y,z]; [null_index(:,1),null_index(:,2),null_index(:,3)]=ind2sub(s,IND);

3)Another idea, since I know my matrix is composed of only three values (122,255,0) would be to come up with a filter (edge detection) that highlights or slightly alters the zero elements that are in any way bordering or touching another element of value 122 or 255. At this point the only zero elements left should be those that have not been adulterated by the filter and Voila! (clearly this idea is still in its infancy and my image processing skills are non-existent at best. Convolution?)

I hope that appropriately describes my problem. This is my first time posting so bare with me. Any help would be much appreciated.

Thank You.

*No products are associated with this question.*

Answer by Teja Muppirala
on 9 May 2013

Accepted answer

As you guessed, there are much simpler ways to do it using image processing techniques.

% Just making some random data to work with m = 122*round(0.51*rand(10,10,10)) + 255*round(0.51*rand(10,10,10));

% Pad the edges with PADARRAY to avoid edge-cases, and then use convolution: mc = convn(padarray(m,[1 1 1],1),ones(3,3,3),'valid'); locations = find(mc == 0); m(locations) = 1;

David
on 9 May 2013

You da man!

Thanks, It worked.

(It gets funky in the first and last planes of the matrix, but I am happy with it. Should speed up my code enough)

David
on 9 May 2013

Okay, back to square one. The above method works great with the only caveat being that it is a memory intensive approach. Inevitably, MATLAB crashes due to memory problems. Is there a more memory friendly approach?

Dave

Related Content

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
## 0 Comments