keep the number give by bwlabel to one object constant in all images of an image sequence

2 views (last 30 days)
Dear readers,
I have a sequence of 10 binary tiff images. In this images there are objects that I can detect by using the bwlabel function.
In the first image I have 3 objects and in the second image I have 4 objects so when I use the bwlabel, the numbers give to the 3 objects is modify because of the new object entering in the field. I want to keep the number give to one object constant in all images. Do you know if it is possible and the way to do it ?
Thank you in advance,
Cheers,
Sophia

Accepted Answer

Image Analyst
Image Analyst on 21 Dec 2018
If you don't have the Automated Driving System Toolbox that Mark mentioned then you can either try to find some tracking code in the Computer Vision System Toolbox, or write it yourself, or look for some open source tracking software.
To write it yourself, what you could do is first accept the labels of the first frame. Then compute all the centroids. Then if you can assume that the centroids did not move very much from one frame to the next, you can use pdist2() in the stats toolbox to find distances of every centroid in frame n+1 to the centroids in frame n. Start out by picking the two closest, and call those a match, assign the label from frame n to frame n+1 (meaning you've determined that they're the same blob), and remove them from consideration. Look at what's left and repeat, basically finding closest pairs, matching labels, and removing from consideration.
When you get down to a few blobs, you'll have to see if they are roughly the same distance away from each other as all the prios blobs. Otherwise you could get a situation where two blobs entered the field of view, and maybe some left the field of view and you'll have a hard time matching them up, so that's why you need to look at the distance and if it's way more than all the other matched distances, then they're probably different blobs, NOT a matched pair.
Writing tracking software is not easy - there are lots of weird pathological cases that need to be handled to do it properly.
  2 Comments
Sophia
Sophia on 21 Dec 2018
Thanks a lot for your answer. I plan to try to write it by myself. The idea that you suggest is the best option I guess. All along my frames objects appear, cross the image, and disappear. They move slowly so we can assume that the centroids did not move very much from one frame to the next. I did not know the pdist2() function and I do not know yet how to integrate it and use it in my code. It is not easy for me because I read my image sequence as a 3D matrix and I used 2 loops (one to run through the frame and one to run through different blobs and follow their properties with regionprops()). Even if my code is far from optimal I share it to you to illustrate what I am trying to explain.
%I cut and copy only the part of the code related to my question.
for i=1:10
figure(i)
imshow(OriginalImage(:,:,i); %OriginalImage is my original image.
hold on;
B = bwboundaries(BWOriginalImage(:,:,i),'noholes');
%BWOriginalImage is the binary
%image associate to BWOriginalImage.
[L(:,:,i),num] = bwlabel(BWOriginalImage(:,:,i));
for k=1:num
b = B{k};
plot(b(:,2),b(:,1),'g','LineWidth',1);
X(k).s(i) = regionprops(L(:,:,i)==k, 'Centroid');
c=X(k).s(i);
text(c.Centroid(1), c.Centroid(2), sprintf('%d', k),'HorizontalAlignment','center','VerticalAlignment','middle');
end
end
% This code displays each frames of my original image, draws boundaries of blobs,
% prints a number in the middle of each blob and returns a structure containing the
% centroid coordinates for each blobs.
Sophia
Sophia on 6 Jan 2019
I tried to use pdist2() as you mentioned but I don't know how to do it. Could you please give me some help or examples ?
Thank a lot,
Sophia

Sign in to comment.

More Answers (2)

Mark Sherstan
Mark Sherstan on 21 Dec 2018
Look at the example located here. If this does not work for you please post your images so that we can help you further.
  1 Comment
Sophia
Sophia on 21 Dec 2018
Thank you for your answer and your example. I will try but I am affraid to do not have the Automated Driving System Toolbox that you mentioned.

Sign in to comment.


Brian Hart
Brian Hart on 21 Dec 2018
Hi Sofia,
I assume these 10 images are related; that they show a changing field.
I think the only way to do what you want is to create a "composite" label matrix, that you update as each new image is processed. I wrote a very basic routine to do this below.
You only mention new objects appearing, so I'll assume new objects appear, but old ones never disappear. You'd have to update the code to handle disappearing objects. But this should get you started.
%create some small binary images, where the second image has one more
%object than the second:
img1 = logical ([ 0 0 0 0 0 0 1 1 1
0 0 1 1 0 0 1 1 1
0 0 1 1 0 0 1 1 1
0 0 0 0 0 0 1 1 1
0 0 0 0 1 0 1 1 1
0 0 0 0 1 0 1 1 1
0 0 0 1 1 0 1 1 1
0 0 0 0 0 0 1 1 1]);
img2 = logical ([ 0 0 0 0 0 0 1 1 1
0 0 1 1 0 0 1 1 1
0 0 1 1 0 0 1 1 1
0 0 0 0 0 0 1 1 1
0 0 0 0 1 0 1 1 1
0 0 0 0 1 0 1 1 1
1 1 0 1 1 0 1 1 1
1 1 0 0 0 0 1 1 1]);
%this shows the problem:
[L1, n1]= bwlabel(img1,4)
[L2, n2]= bwlabel(img2,4) %here the objects from img1 have different numbers.
%Put the images in a 3d array for in-loop indexing:
imgArr(:,:,1) = img1;
imgArr(:,:,2) = img2;
numImgs = size(imgArr,3);
%create all-zero "composite" L to start:
compL = img1 * 0;
%Now evaluate each image, adding _new_ objects to the composite L in
%series:
for i = 1:numImgs
[L, n] = bwlabel(imgArr(:,:,i));
if i==1
compL = L; %use the first image L as the starting composite L
numTotalObjs = n;
else
L(compL ~= 0) = 0; %zero out already-identified objects
newObjs = unique(L);
numNewObjs = length (newObjs) - 1; %assume there's always a zero
if numNewObjs > 0
for j = 1:numNewObjs
compL(L==newObjs(j+1)) = numTotalObjs + j;
end
numTotalObjs = numTotalObjs + numNewObjs;
end
end
end
%Now compL should have the first three objects labeled as in L1, with the
%new object from L2 labeled as "4"
  3 Comments
Sophia
Sophia on 21 Dec 2018
Hi Brian,
Thanks for your answer and your code. Yes I forgot to tell you that objects appear and disappear and their shape change a bit... I will try your code by the way and see what happens. It could not work if the existing blobs in the later images have to be exactly the same pixels as in the prior image as suggested by Image Analyst.
Sophia
Brian Hart
Brian Hart on 21 Dec 2018
Yes; this basic example depends on the detected pixels remaining constant. If they move a bit, then adding a dilation to the line Image Analyst quoted could help.
The primary question seemed to be how to manipulate the per-image results to maintain an overall object numbering and count. I think the provided algorithm shows a way to do that.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!