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

3 views (last 30 days)
Sophia on 20 Dec 2018
Commented: Sophia on 6 Jan 2019
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,

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.
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,

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 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
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;
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;
numTotalObjs = numTotalObjs + numNewObjs;
%Now compL should have the first three objects labeled as in L1, with the
%new object from L2 labeled as "4"
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!

Translated by