如何使用javacv / opencv识别黑色多边形上的点?

时间:2012-10-19 11:34:42

标签: image-processing opencv javacv

我尝试识别这个黑色多边形周围的轮廓,我需要访问这些点,但它对我不起作用。这是输入图像 enter image description here

但是,当我尝试执行以下代码时,它没有给出预期的结果,这意味着它应该。

        CanvasFrame cnvs=new CanvasFrame("Polygon");
        cnvs.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

        CvMemStorage storage=CvMemStorage.create();
        CvSeq squares = new CvContour();
        squares = cvCreateSeq(0, sizeof(CvContour.class), sizeof(CvSeq.class), storage);
        String path="project/Test/img/black.png";
        IplImage src = cvLoadImage(path);
        IplImage gry=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
        cvCvtColor(src, gry, CV_BGR2GRAY);
        cvThreshold(gry, gry, 230, 255, CV_THRESH_BINARY_INV);
        cnvs.showImage(gry);
        cvFindContours(gry, storage, squares, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
        CvSeq ss=null;
        CvSeq tmp=null;
        int ii=0;
            for (ss=squares; ss!=null; ss=ss.h_next()) {
                tmp=cvApproxPoly(ss, sizeof(CvContour.class), storage, CV_POLY_APPROX_DP, 8, 0);
                System.out.println("index "+ii+" points "+tmp.total()+" area "+cvContourArea(ss, CV_WHOLE_SEQ, 0));
                cvDrawContours(src, ss, CvScalar.RED, CV_RGB(248, 18, 18), 1, -1, 8);
                //drawPoly(src, tmp);
            }
        IplConvKernel mat=cvCreateStructuringElementEx(7, 7, 3, 3, CV_SHAPE_RECT, null);
        cvDilate(src, src, mat, CV_C);
        cvErode(src, src, mat, CV_C);
        cnvs.showImage(src);
        saveImage("nw.png", src);

但是当我检查出来时它只给出了

指数0点8区20179.0

这意味着它只识别多边形的8个点,但它应该是12个点。 请一些人解释这段代码的问题。

这显示了输出图像

enter image description here

1 个答案:

答案 0 :(得分:1)

cvApproxPoly()函数使用Ramer–Douglas–Peucker算法进行曲线近似。该算法的目的是找到具有较少点的类似曲线。算法本身将两个参数作为输入:

  • 点列表(顶点),
  • 近似准确度。

简而言之,aproximation acuracy值越大,在aproximated曲线中省略该点的机会就越大(请参阅Wikipedia article,尤其是this动画)。在你的函数调用中:

cvApproxPoly(ss, sizeof(CvContour.class), storage, CV_POLY_APPROX_DP, 8, 0);

第五个参数是近似精度。如果您不想减少顶点数,则该值应该很小(对于此示例,大约1的值恰好给出12个顶点,因此没有近似值。)