Как определить точки на черном многоугольнике с помощью javacv/opencv?

Я пытаюсь определить контур вокруг этого черного многоугольника, и мне нужно получить доступ к этим точкам, но у меня это не работает. Это входное изображение введите здесь описание изображения

Но когда я пытаюсь сделать следующий код, он не дал ожидаемого результата, а значит, должен.

        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 точек. Пожалуйста, может кто-нибудь объяснить проблему этого кода.

Это показывает выходное изображение

введите здесь описание изображения


person LkDev    schedule 19.10.2012    source источник


Ответы (1)


Функция cvApproxPoly() использует Ramer–Douglas–Peucker алгоритм аппроксимации кривой. Цель алгоритма — найти аналогичную кривую с меньшим количеством точек. Сам алгоритм принимает на вход два параметра:

  • список точек (вершин),
  • точность приближения.

Вкратце, чем больше значение точности аппроксимации, тем выше вероятность того, что точка будет опущена на аппроксимируемой кривой (см. Википедию статья, особенно эту анимацию). В вашем вызове функции:

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

5-й параметр — точность аппроксимации. Если вы не хотите уменьшать количество вершин, значение должно быть небольшим (для этого примера значения около 1 дают ровно 12 вершин, поэтому нет приближения).

person majkel.mk    schedule 27.10.2012