3

I would like to use some blob detection in my application which is written in Java and thus using JavaCV instead of OpenCV. I found many classes like:

SimpleBlobDetector, CvBlobDetector, CvBlob, ... but I can't find any tutorial or demo/example code to use these in Java. Could anyone please tell me how to use these as I can't figure it out and there's no good documentation for them. Thanks!

adn
  • 897
  • 3
  • 22
  • 49
hhoud
  • 518
  • 2
  • 6
  • 18
  • 1
    The JavaCV API maps as closely as possible the C/C++ API. If you can find some documentation or sample written in C/C++, it should not be too hard to translate that to Java... – Samuel Audet Mar 12 '12 at 11:08

2 Answers2

8

I am just in this moment working on the same problem and have a first solution. There's a lot of approaches out there but unfortunately most of them are ugly and slow. My main goal to this point was to stay in the JavaCV/OpenCV-World.

These Links pushed me in the right direction:

  1. Blob extraction in OpenCV
  2. http://voices.yahoo.com/connected-components-using-opencv-5462975.html?cat=15
  3. http://opencv.willowgarage.com/documentation/cpp/structural_analysis_and_shape_descriptors.html#cv-findcontours

Here's a complete Demo class that should show you how it's done. Try it with a black background image with simple objects and sharp corners for best results. Make sure to check the second link above to get informed about what's happening in the code.

import static com.googlecode.javacpp.Loader.sizeof;
import static com.googlecode.javacv.cpp.opencv_core.CV_FILLED;
import static com.googlecode.javacv.cpp.opencv_core.CV_RGB;
import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateMemStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvDrawContours;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_core.cvPoint;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_BGR2GRAY;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_CHAIN_APPROX_SIMPLE;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_RETR_CCOMP;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_THRESH_BINARY;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCvtColor;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvFindContours;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvThreshold;

import java.awt.Color;
import java.util.Random;

import com.googlecode.javacv.cpp.opencv_core.CvContour;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

/**
 * A demo for blob extraction using only JavaCV / OpenCV
 * @see https://stackoverflow.com/questions/4641817/blob-extraction-in-opencv
 * @see http://voices.yahoo.com/connected-components-using-opencv-5462975.html?cat=15
 * @see http://opencv.willowgarage.com/documentation/cpp/structural_analysis_and_shape_descriptors.html#cv-findcontours
 * @author happyburnout
 */

public class JavaCVBlobDemo {

    static String sourcePath = "c:/test/source.jpg";
    static String targetPath = "c:/test/target.jpg";

    public static void main (String args[]){
        IplImage image = cvLoadImage(sourcePath);
        IplImage grayImage = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
        cvCvtColor(image, grayImage, CV_BGR2GRAY);

        CvMemStorage mem;
        CvSeq contours = new CvSeq();
        CvSeq ptr = new CvSeq();
        cvThreshold(grayImage, grayImage, 150, 255, CV_THRESH_BINARY);
        mem = cvCreateMemStorage(0);

        cvFindContours(grayImage, mem, contours, sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

        Random rand = new Random();
        for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
            Color randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());
            CvScalar color = CV_RGB( randomColor.getRed(), randomColor.getGreen(), randomColor.getBlue());
            cvDrawContours(image, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
        }
        cvSaveImage(targetPath, image);
    }

}
Community
  • 1
  • 1
happyburnout
  • 139
  • 4
-2
public static IplImage detectObjects(IplImage srcImage){

    IplImage resultImage = cvCloneImage(srcImage);

    CvMemStorage mem = CvMemStorage.create();
    CvSeq contours = new CvSeq();
    CvSeq ptr = new CvSeq();

    cvFindContours(srcImage, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    CvRect boundbox;

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
        boundbox = cvBoundingRect(ptr, 0);

        cvRectangle( resultImage, cvPoint( boundbox.x(), boundbox.y() ), cvPoint( boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),cvScalar( 0, 255, 255, 0 ), 3, 0, 0 ); 
    }

    return resultImage;
}
Keshan De Silva
  • 839
  • 1
  • 11
  • 25
  • yep... 'box' should be replaced with 'boundbox'. What you really means by incomplete. This method is complete and it is working for me. Please comment what part will give errors. – Keshan De Silva May 29 '12 at 02:57
  • cvRectangle( resultImage, cvPoint( box.x(), box.y() ), cvPoint( box.x() + box.width(), box.y() + box.height()), <- the line isn't even finished – Tanner May 29 '12 at 17:14
  • Sorry for that i missed that part when i copied the code from project. – Keshan De Silva May 31 '12 at 03:18
  • cvRectangle( resultImage, cvPoint( box.x(), box.y() ), cvPoint( box.x() + box.width(), box.y() + box.height()),cvScalar( 0, 255, 255, 0 ), 3, 0, 0 ); – Keshan De Silva May 31 '12 at 03:21
  • 1
    this is a code segment from my final year research project. This is working fine. SO if you have any problem with this code please let me know. thankx.. – Keshan De Silva May 31 '12 at 03:21
  • What is the "cvBoundingRect" method in this code. I can't find that method when I try to call it??? – SL_User Jun 19 '12 at 06:01
  • cvBoundingRect is a method that is available at `com.googlecode.javacv.cpp.opencv_imgproc` – Keshan De Silva Jun 20 '12 at 09:55