如何在javacv中获取提取对象的x,y坐标?

时间:2012-08-24 09:07:34

标签: java opencv image-processing javacv

目前我正在开发图像处理项目,我正在使用javacv开发图像处理组件。我能够提取图像的一些有趣部分,现在我需要读取这些对象的x和y坐标。 这是我提取的图像

enter image description here

我需要识别这些对象并围绕这些对象绘制正方形。我浏览了一些教程并尝试使用以下代码识别对象。

    IplImage img="sourceimage";
    CvSize sz = cvSize(img.width(), img.height());
    IplImage gry=cvCreateImage(sz, img.depth(), 1);
    cvCvtColor(img, gry, CV_BGR2GRAY);
    cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY);


    CvMemStorage mem = CvMemStorage.create();
    CvSeq contours = new CvSeq();
    CvSeq ptr = new CvSeq();
    cvFindContours(gry, 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);
        if(boundbox.height()>10||boundbox.height()>10){
            cvRectangle( gry, cvPoint( boundbox.x(), boundbox.y() ), cvPoint( boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0 );
            System.out.println(boundbox.x()+", "+boundbox.y());
        }
    }
    cvShowImage("contures", gry);
    cvWaitKey(0);

但它并没有在对象周围画出矩形。我想知道我是否可以使用cvFindContours方法来识别这些对象?请问有人可以解释如何使用javacv / opencv归档我的目标吗?

5 个答案:

答案 0 :(得分:11)

尝试通过以下代码,它将为您的问题提供答案。

    IplImage img=cvLoadImage("pathtosourceimage");
    CvSize cvSize = cvSize(img.width(), img.height());
    IplImage gry=cvCreateImage(cvSize, img.depth(), 1);
    cvCvtColor(img, gry, CV_BGR2GRAY);
    cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY);
    cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5);

    CvMemStorage storage = CvMemStorage.create();
    CvSeq contours = new CvContour(null);

    int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0));

    CvSeq ptr = new CvSeq();

    int count =1;
    CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0);

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) {

        CvScalar color = CvScalar.BLUE;
        CvRect sq = cvBoundingRect(ptr, 0);

            System.out.println("Contour No ="+count);
            System.out.println("X ="+ sq.x()+" Y="+ sq.y());
            System.out.println("Height ="+sq.height()+" Width ="+sq.width());
            System.out.println("");

            p1.x(sq.x());
            p2.x(sq.x()+sq.width());
            p1.y(sq.y());
            p2.y(sq.y()+sq.height());
            cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0);
            cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
            count++;

    }

    cvShowImage("contures",img);
    cvWaitKey(0);

这是我为您的图像输出的。

enter image description here

答案 1 :(得分:4)

cvFindContours是您解决问题的正确方法 我已经确认它适用于您的图像 Here is my experiment

你的System.out.println里面有什么输出?

cvFindContours可能很难使用,我把它包装成more general C++ function。我还使用class called vBlob来描述cvFindContours检测到的对象。从我从java代码中看到的,java版本API与C / C ++版本非常相似。所以重写它并不难。

PS。阿斯特给出了正确答案。

答案 2 :(得分:4)

您是否知道findContours函数在黑色背景上找到白色轮廓?

只需对您的图片执行bitwise_not(或类似于JavaCV),然后应用findContours。这实际上解决了你的问题。

答案 3 :(得分:4)

不需要第三方库!使用称为bounding box的技术可以在OpenCV中实现您的目标:

enter image description here

诀窍是使用cvFindContours()检索轮廓,然后使用cvApproxPoly()来改善结果。请注意,您必须使用cvNot()反转输入图像的颜色,因为cvFindContours()会搜索白色轮廓。

  • this post中的轮廓进行了很好的介绍。
  • 有一个Java demo实现了一个版本的边界框来检测车牌号。

顺便说一句cvMinEnclosingCircle()将圆圈的中心返回为CvPoint2D32f

答案 4 :(得分:2)

我使用的是c ++ api,但我认为在javacv中也应该有一些名为drawContours或cvDrawContours的函数,它使用了findContours的输出。