简体   繁体   English

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

[英]How to get x,y coordinates of extracted objects in javacv?

Currently I am developing image processing project and I'm using javacv to develop image processing components. 目前我正在开发图像处理项目,我正在使用javacv开发图像处理组件。 I was able to extract some interesting parts of a image and now I need to read the x and y coordinates of those objects. 我能够提取图像的一些有趣部分,现在我需要读取这些对象的x和y坐标。 This is the image that I haveextracted 这是我提取的图像

在此输入图像描述

And I need to identify those objects and draw square around those objects. 我需要识别这些对象并围绕这些对象绘制正方形。 I went through some tutorials and try to identify objects using following code. 我浏览了一些教程并尝试使用以下代码识别对象。

    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);

But it doesn't draw as rectangle around the objects. 但它不会在对象周围绘制为矩形。 I would like to know whether I can use cvFindContours method to identify those objects ? 我想知道我是否可以使用cvFindContours方法来识别这些对象? Please can some one explain how to archive my objective using javacv/opencv? 请问有人可以解释如何使用javacv / opencv存档我的目标吗?

Try to go through following code and it will give answer for your question. 尝试通过以下代码,它将为您的问题提供答案。

    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);

This is the output that I got for your given image. 这是我给你的图像得到的输出。

在此输入图像描述

cvFindContours is the right solution to your problem. cvFindContours是解决您问题的正确方法。
And I have verified that it works on your images. 我已经确认它适用于您的图像。
这是我的实验

You have System.out.println inside, what's the output? 你有System.out.println,输出是什么?

cvFindContours could be tricky to use, I have wrapped it into a more general C++ function . 使用cvFindContours可能很棘手,我把它包装成更通用的C ++函数 Also I use a class called vBlob to describe an object cvFindContours detects. 我还使用一个名为vBlob来描述cvFindContours检测到的对象 From what I see from your java code, java version API is very similar to C/C++ version. 从我从java代码中看到的,java版本API与C / C ++版本非常相似。 So it won't be hard to rewrite it. 所以重写它并不难。

ps. PS。 Astor gave the right answer. 阿斯特给出了正确的答案。

Did you know that findContours function finds white contours on black background? 你知道findContours函数在黑色背景上找到白色轮廓吗?

Just do bitwise_not (or analogue in JavaCV) to your image and after this apply findContours . 只需对您的图像执行bitwise_not (或bitwise_not模拟),然后应用findContours This is actually fix to your problem. 这实际上是解决您的问题。

No need for third party libraries! 不需要第三方库! What you are looking for can be achieved in OpenCV using a technique known as bounding box : 您正在寻找的是使用称为边界框的技术在OpenCV 中实现的

在此输入图像描述

The trick is to use cvFindContours() to retrieve the contours and then cvApproxPoly() to improve the result. 诀窍是使用cvFindContours()来检索轮廓,然后使用cvApproxPoly()来改善结果。 Notice that you'll have to invert the colors of the input image using cvNot() because cvFindContours() search for white contours. 请注意,您必须使用cvNot()反转输入图像的颜色,因为cvFindContours()搜索白色轮廓。

  • There's a nice introduction to contours in this post . 这篇文章中有关于轮廓的很好的介绍。
  • There's a Java demo that implements a version of the bounding box to detect car number plates. 有一个Java演示实现了一个版本的边界框来检测车牌号。

By the way cvMinEnclosingCircle() returns the center of the circle as CvPoint2D32f . 顺便说一句, cvMinEnclosingCircle()返回圆的中心为CvPoint2D32f

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM