Ordered connected components
Show older comments
For connected components found by using bwconncomp(), the PixelIdxList is ordered according to columns and then rows. Is there a way to obtain the list of the pixels in the order in which they are connected?
My connected components are edges. I have tried bwtraceboundary(), but it yields a circular path along the edge, with most pixels except the start and end points being repeated. Besides, some intermediate pixels occur only once due to the order in which the connected pixels are searched for.
So, is there a better way to obtain a list of component pixels in connected order?
5 Comments
Dustin
on 6 Aug 2011
Sean de Wolski
on 6 Aug 2011
Can you provide us with a picture and the few lines of code. What about post sorting the PixelIdxList? What about labelling the image and then calling bwconncomp (or my label2CC on the FEX) which will keep the order of the labels?
Dustin
on 6 Aug 2011
Image Analyst
on 7 Aug 2011
Dustin: Can you take a step back and tell us why you think that you need an ordered list of which pixels are contained in the object? I have used the pixels in the object before but it was never needed that they be in some special or known order - I was able to do what I want to do without regard to that. What are you really trying to do?
Dustin
on 12 Aug 2011
Accepted Answer
More Answers (3)
Wolfgang Schwanghart
on 6 Aug 2011
Hi Dustin,
I don't have MATLAB at hand right now, so I cannot try, but I think bwboundaries should solve your problem.
[B,L,N,A] = bwboundaries(BW,8,'noholes')
The adjacency matrix should contain the information you need.
Cheers, Wolfgang
4 Comments
Dustin
on 6 Aug 2011
Wolfgang Schwanghart
on 6 Aug 2011
How would your path go then?
0 0 2 1
0 3 0 0
0 4 5 0
0 0 6 7
or would that be ok, too?
0 0 2 1
0 3 0 0
0 4 0 0
0 0 5 6
or this?
0 0 2 1
0 3 0 0
0 4 5 0
0 0 0 6
Dustin
on 7 Aug 2011
Image Analyst
on 7 Aug 2011
Then just use bwboundaries with 4-connectivity and that's what you'll get.
Sean de Wolski
on 7 Aug 2011
Use regionprops on the CC struct with the 'PixelList' option. That will return row/columns. Then use sortrows on that to find the order, keep the linear index and apply it:
I = logical([0 0 0 1 0 0 0 0 1 0;...
0 0 1 0 0 0 0 0 1 0;...
0 0 1 0 0 0 0 0 0 1;...
0 1 0 0 0 0 0 0 1 0;...
1 0 0 0 0 0 0 1 1 0;...
0 0 0 0 0 0 1 1 0 0]);
CC = bwconncomp(I); %cc struct
rp = regionprops(CC,'pixellist'); %subindexes
the_order = cell(1,CC.NumObjects); %preallocate
for ii = 1:CC.NumObjects
[junk the_order{ii}] = sortrows(rp(ii).PixelList,[1 -2]); %sort, only keep the order to extract
end
CCnew = CC; %copy
CCnew.PixelIdxList = cellfun(@(old,idx)old(idx),CC.PixelIdxList,the_order,'uni',false); %set copy to modified order
To view and check against your provided example:
CCnew.PixelIdxList{:} %woo!
kevin
on 30 Mar 2014
The bwdistgeodesic function can help you with the 'cityblock' or ' quasi-euclidean ' method :
For example, if you choose the first edge point(x1,y1) and you compute bwdistgeodesic(bw,y1,x1,'cityblock'), you will get a distance matrix whose values will be in the range [0 : number of connected components -1]. At the location (x1,y1) of your first point , the distance matrix value will be 0, those of the next pixel will be 1, the next 2 , etc... The order gives priority to 4-connectivity, I think it is that you want. Then you just have to sort the values to get your ordered list.
An example :
selected = bwselect(bw,y1,x1);
mat_dist = bwdistgeodesic(selected,y1,x1,'cityblock'); %'quasi-euclidean' for 8-connectivity
comp = find(selected);
comp(:,2) = mat_dist(comp(:,1));
ordered_list_ind = sortrows(comp,2);
[ordered_list_sub(:,1) ordered_list_sub(:,2)] = ind2sub(size(selected),ordered_list_ind(:,1));
Remarks : The 'cityblock' method works only for 4-connectivity. If you need this for 8-connectivity, replace the 'cityblock' method by the 'quasi-euclidean' one, sorting the values will allow the same result for 8-c.
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!