MATLAB: Connect bwlabeled components

digital image processingimage segmentationlinear algebraMATLABparticle trackingregionprops

[EDIT: 20110623 22:06 CDT – reformat – WDR]
Hello, I need help on a very simple task…well..seemingly.
except I have a tiff stack with numerous layers in series. In this image the blobs move around as one goes deeper into the tiff stack series (it is a spatial not temporal series). I am trying to do the following:
Find all unique objects per layer, connect objects from one plane to another that 'overlap'(thus indicating that both object x1 in layer a and x2 in layer b are the same object just at different spatial depths) as a line segment, generate a output with orientation in z of each line segment.
I have done the first instant. I am looking for advice on how to go about the object grouping, ie. connecting the same 'real object' in the serialized sections.
Any functions I should look at? Particle tracking functions perhaps?
Cheers,

Best Answer

Using bwconncomp on a three dimensional image will group them in 3d. You'll have to call it on each individual slice to see how many objects per slice there are:
sliceObjs = zeros(size(stack,3),1);
for ii = 1:size(stack,3)
CC = bwconncomp(stack(:,:,ii));
sliceObjs(ii) = CC.NumObjects;
end
EDIT This is a script, with the engine completely generalized and ready to go. I saved you above image; cropped it and translated it for visualization error checking purposes. The translation was done using my function FEX:imtranslate
%%Data and stuff
I = imread('ans627.png'); %your image
I = I(35:276,86:381,1)==255; %keep relevant part; convert to binary
I(:,:,2) = imtranslate(I,[10 -14]); %artificially translate for testing
I(5:11,270:275,2) = true; %add an eleventh object with no friends
szI = size(I);
Ds = cell(szI(3)-1); %preallocate place to store stuff
CCold = bwconncomp(I(:,:,1)); %cc of first slice
RPold = regionprops(CCold,'centroid');
centsA = vertcat(RPold(:).Centroid); %extract centroids
for ii = 1:(szI(3)-1)
CCnew = bwconncomp(I(:,:,ii+1)); %cc of next slice
RPnew = regionprops(CCnew,'centroid');
centsB = vertcat(RPnew(:).Centroid);
dim = 2; %which dimension will control in the bsxfun expression?
if CCold.NumObjects>CCnew.NumObjects
dim = 1;
end
%Engine:
xyDiff = bsxfun(@(x,y)abs(x-y),reshape(centsA,[],1,2),reshape(centsB,1,[],2)); %Centroids distances in each dimension
[~,idx] = min(hypot(xyDiff(:,:,1),xyDiff(:,:,2)),[],dim);
if dim==2;
displacements = centsB(idx,:)-centsA;
H = quiver(centsA(:,1),centsA(:,2),displacements(:,1),displacements(:,2));
else
displacements = centsB-centsA(idx,:);
H = quiver(centsB(:,1),centsB(:,2),displacements(:,1),displacements(:,2));
end
RPold = RPnew; %get ready to move on
CCold = CCnew;
centsA = centsB;
Ds{ii} = displacements; %can store other stuff too.
end
%SCd 06/27/2011
If you now look at displacements, you'll see that the artificial translation was recovered. I didn't place a threshold on distance - just used the minimum one. This could be added easily enough. (replace objects without a match to nan to maintain order)