How to find zero elements in a three dimensional matrix whose neighbors are all zero.

7 views (last 30 days)
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.

Accepted Answer

Teja Muppirala
Teja Muppirala on 9 May 2013
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;
  2 Comments
David
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
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

Sign in to comment.

More Answers (0)

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!