gparadis / cvblob

Automatically exported from code.google.com/p/cvblob
GNU Lesser General Public License v3.0
0 stars 0 forks source link

relabel blobs after cvFilterByArea (feature request) #19

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
When I'm using cvLabel on my image I'm getting 100 blobs.
Most of the blobs are too small so I'm using cvFilterByArea to get the real 20 
blobs.

It works well but then the blob label is not the same as the blob index in the 
blobs vector.
I need to calculate some kind of distance matrix between the blobs and order 
them in a dendrogram but the fact that the label is different from the index in 
the vector makes it complicated. To solve it I need to save a map of 
label->index and check it every time.

I thought of several way to solve it:
1. Have a new function cvRelabel(blobs, label) which makes sure the blob label 
is the same as its index.
2. Two optional argument to cvLabel, minArea and maxArea to filter blobs when 
finding them.
3. cvFilterByArea could take the label as an argument and change the labels of 
the blobs and in the img after removing the not needed blobs.

Makes sense to add one of the options to cvBlob?
Thanks

Original issue reported on code.google.com by pablo.platt@gmail.com on 12 Jan 2011 at 10:43

GoogleCodeExporter commented 8 years ago
I've implemented cvRelabel and it works well for me:

void cvRelabel(CvBlobs blobs, IplImage* imgLabel) {
    int i=1;
    int stepLbl = imgLabel->widthStep/(imgLabel->depth/8);
    for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it, i++) {
        CvBlob* blob = it->second;
        if(blob->label != i) {            
            for(int y=0; y<imgLabel->height; y++ ) {
                CvLabel *label = (CvLabel *) imgLabel->imageData + y * stepLbl;
                for(int x=0; x<imgLabel->width; x++) {
                    if(*label == blob->label) {
                        *label = i;  
                    }
                    label++;
                }
            }
            blob->label = i;
        }
    }
}

Original comment by pablo.platt@gmail.com on 12 Jan 2011 at 11:11

GoogleCodeExporter commented 8 years ago
Hi Pablo,

CvBlobs is not a `vector` but a `map`. This way the "indexes" don't change when 
you filter blobs. I used maps for that reason. For example, you have:

  blobs[0], blobs[1], blobs[2], blobs[3]

After filter you could have:

  blobs[1], blobs[3]

Of course, if you use iterators you'll see that the "first" blobs has 
`label=1`, and next blob has `label=3`, but their indexes are the same. If you 
need to know the "index" of a iterator you can use `it->first`, but it should 
be the equal to `it->second->label`.

So, do a relabel or something like that seems unnecessary to me :-S Can you 
overcome the problem in any other way?

I could refactor all the library and use only vector instead of maps (vector 
must be more efficient), but I find maps easier when you program.

Regards,

Cristóbal

Original comment by grendel....@gmail.com on 13 Jan 2011 at 9:57