Skip to main content

Blobs with opencv (internal function)

There are many open source opencv BLOB libraries that you can use. i have tried several of these, however because of the 64 bit machine that im using recompiling these are very troublesome.

If you have heard of these libraries:
  1. "cvBlobsLib": http://opencv.willowgarage.com/wiki/cvBlobsLib 
  2. "cvBlob": http://code.google.com/p/cvblob/ 
  3. "Bloblib" by Dave Grossman (also referred to as "Blob Analysis Package"):
    Go to http://tech.groups.yahoo.com/group/OpenCV/files/
 You will know that opencv also has a built in function that can help you find blobs using cv::findContour and see some statistics using the cv::moments.
eventually make these functions similar to regionprops Matlab function


The BLOB FINDER CLASS:
class atsBlobFinder
{
public:
    atsBlobFinder(cv::Mat src)
    {
        numBlobs = 0;
        cv::Mat img; //must create a temporary Matrix to hold the gray scale or wont work
        cv::cvtColor(src,img,CV_BGR2GRAY); //Convert image to GrayScale
        img = img > 1; //create the binary image
        ////cv::adaptiveThreshold(src,src,64,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,7,13); //create a binary image
       
        findContours( img, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); //Find the Contour BLOBS
        vector<Moments> _mu(contours.size() );
        vector<Point2f> _mc( contours.size() );
        for( int i = 0; i < contours.size(); i++ )
        {
            _mu[i] = moments( Mat(contours[i]), false );
            _mc[i] = Point2f( _mu[i].m10/_mu[i].m00 , _mu[i].m01/_mu[i].m00);
        }
        mu = _mu;
        mc = _mc;
        numBlobs = contours.size();
    }
    void Draw(cv::Mat &dst)
    {
        // iterate through all the top-level contours,
        // draw each connected component with its own random color
        for( int i = 0; i < contours.size(); i++ )
        {
            Scalar color(  rng.uniform(0,255),  rng.uniform(0,255),  rng.uniform(0,255) );
            drawContours( dst, contours, i, color, CV_FILLED, 8, hierarchy );
            // drawCross(mc[i],Scalar(0,0,255), 5,dst); //put a cross
            char buff[255];
            sprintf(buff, "%d", i);

            string text = std::string(buff);
            cv::putText(dst,text,mc[i],0,0.5,Scalar(0,0,255),1,8,false);
        }
    }
    int getNumBlobs()
    {
        //need to create a buffer for output or wrong reference
        /*char buff[255];
        sprintf(buff, "%d", numBlobs);*/
        return numBlobs;
    }
private:
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    vector<Moments> mu;
    vector<Point2f> mc;
    int numBlobs;
};




#include <iostream>

// Include OpenCV
#include <opencv/cv.h>
#include <opencv/highgui.h>

using namespace cv;
#define drawCross( center, color, d, drawing )                                 \
            line( drawing, Point( center.x - d, center.y - d ),                \
            Point( center.x + d, center.y + d ), color, 2, CV_AA, 0); \
            line( drawing, Point( center.x + d, center.y - d ),                \
            Point( center.x - d, center.y + d ), color, 2, CV_AA, 0 )

RNG rng(12345);
int main( int argc, char** argv )
{
    Mat src;
    // the first command line parameter must be file name of binary
    // (black-n-white) image
    if(!(src=imread("pic6.png", CV_LOAD_IMAGE_GRAYSCALE)).data)
    {
        printf("OOOPS");
        waitKey(0);
        return -1;
    }



    Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);

    src = src > 1;
    //cv::adaptiveThreshold(src,src,64,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,7,13);
    namedWindow( "Source", 1 );
    imshow( "Source", src );

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours( src, contours, hierarchy,
        CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

    /// Get the moments
    vector<Moments> mu(contours.size() );
    vector<Point2f> mc( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        {
            mu[i] = moments( Mat(contours[i]), false );
            mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00);
        }

    // iterate through all the top-level contours,
    // draw each connected component with its own random color
    for( int i = 0; i < contours.size(); i++ )
    {
        Scalar color(  rng.uniform(0,255),  rng.uniform(0,255),  rng.uniform(0,255) );
        drawContours( dst, contours, i, color, CV_FILLED, 8, hierarchy );
        // drawCross(mc[i],Scalar(0,0,255), 5,dst); //put a cross
         char buff[255];
        sprintf(buff, "%d", i);

         string text = std::string(buff);
        cv::putText(dst,text,mc[i],0,0.5,Scalar(0,0,255),1,8,false);
    }
   

    namedWindow( "Components", 1 );
    imshow( "Components", dst );
    waitKey(0);
}

Comments

  1. Ty!
    I loved your code.
    you can use filter2D, threshold and Canny to make more precise !
    ty again !

    ReplyDelete
  2. hi,How we use cvblob in matlab ,help me
    Please

    ReplyDelete

Post a Comment

Popular posts from this blog

Computing Entropy of an image (CORRECTED)

entropy is a measure of the uncertainty associated with a random variable. basically i want to get a single value representing the entropy of an image. 1. Assign 255 bins for the range of values between 0-255 2. separate the image into its 3 channels 3. compute histogram for each channel 4. normalize all 3 channels unifirmely 5. for each channel get the bin value (Hc) and use its absolute value (negative log is infinity) 6. compute Hc*log10(Hc) 7. add to entropy and continue with 5 until a single value converges 5. get the frequency of each channel - add all the values of the bin 6. for each bin get a probability - if bin 1 = 20 bin 2 = 30 then frequency is 50 and probability is 20/50 and 30/50 then compute using shannon formula  REFERENCE: http://people.revoledu.com/kardi/tutorial/DecisionTree/how-to-measure-impurity.htm class atsHistogram { public:     cv::Mat DrawHistogram(Mat src)     {         /// Separate the image in 3 places ( R, G and B )    

Blob Detection, Connected Component (Pure Opencv)

Connected-component labeling (alternatively connected-component analysis, blob extraction, region labeling, blob discovery, or region extraction) is an algorithmic application of graph theory, where subsets of connected components are uniquely labeled based on a given heuristic. Connected-component labeling is not to be confused with segmentation. i got the initial code from this URL: http://nghiaho.com/?p=1102 However the code did not compile with my setup of OpenCV 2.2, im guessing it was an older version. so a refactored and corrected the errors to come up with this Class class atsBlobFinder     {     public:         atsBlobFinder()         {         }         ///Original Code by http://nghiaho.com/?p=1102         ///Changed and added commments. Removed Errors         ///works with VS2010 and OpenCV 2.2+         void FindBlobs(const cv::Mat &binary, vector < vector<cv::Point>  > &blobs)         {             blobs.clear();             // Fill the la

Region of interest selection ROI

#include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h> #include<opencv2\opencv.hpp> #include <opencv2\highgui\highgui.hpp> int main(int argc, char *argv[]) { CvCapture *capture = 0; IplImage *frame = 0; int key = 0; /* initialize camera */ capture = cvCaptureFromCAM( 0 ); /* always check */ if ( !capture ) { printf("Cannot open initialize webcam!\n" ); exit(0); } /* create a window for the video */ cvNamedWindow( "result", CV_WINDOW_AUTOSIZE ); while( key != 'q' ) { /* get a frame */ frame = cvQueryFrame( capture ); /* always check */ if( !frame ) break; /* sets the Region of Interest*/ cvSetImageROI(frame, cvRect(150, 50, 150, 250)); /* create destination image */ IplImage *img2 = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels); /* * do the main processing with subimage here. * in this example, we simply invert the subimage