Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify points on black polygon using javacv/opencv?

I try to identify Contour around this black polygon and I need to access those points but it doesn't work for me. This is the input image enter image description here

But when I try to do following code It didn't gave the expected result which means it should.

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

But when I check the out put it gives only

index 0 points 8 area 20179.0

That means it only identify 8 points of the polygon but it should be 12 points. Please can some one explain problem of this code.

This show the out put image

enter image description here

like image 392
LkDev Avatar asked Nov 13 '22 20:11

LkDev


1 Answers

The cvApproxPoly() function uses Ramer–Douglas–Peucker algorithm for curve approximation. The purpose of the algorithm is to find a similar curve with fewer points. The algorithm itself takes two parameters as input:

  • list of points (vertices),
  • aproximation accuracy.

Briefly, the greater the aproximation acuracy value, the bigger chance to the point being omitted in aproximated curve (please refer to the Wikipedia article, especially this animation). In your function call:

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

the 5th parameter is the aproximation accuracy. If you don't want to reduce number of vertices the value should be small (for this example values around 1 give exactly 12 vertices, therefore no approximation).

like image 108
majkel.mk Avatar answered Nov 15 '22 13:11

majkel.mk