2017-01-17 3 views
0

Я сейчас пытаюсь закрыть контуры, расположенные справа от этой фотографии: Sample. Причина открытого контура лежит в kabeja, библиотеке для преобразования файлов DXF в изображения. Похоже, что на некоторых изображениях он не преобразует последний столбец пикселей (или строку), поэтому изображение образца открыто.OpenCV - Закрытие контуров (Java)

У меня была идея использовать Core.copyMakeBorder() в Opencv, чтобы добавить место на картинке. После этого я попытался использовать Imgproc.approxPolyDP(), чтобы закрыть контур, но это не сработает. Я пробовал это с разными значениями Epsilon: Pics EDIT: не может размещать более двух ссылок

Причина в том, что контур окружает линию. Он никогда не закрывает контур, где я хочу, чтобы он делал.

Я попробовал другой метод, используя Imgproc.convexHull(), который поставляет этот: ConvexHull. Это может быть полезно для меня, но я понятия не имею, как вынуть часть выпуклого корпуса, который мне нужен, и объединить его вместе с контуром, чтобы закрыть его.

Я надеюсь, что у кого-то есть идея.

Вот мой метод Imgproc.approxPolyDP()

public static ArrayList<MatOfPoint> makeComplete(Mat mat) { 
    System.out.println("makeComplete: START"); 
    Mat dst = new Mat(); 
    Core.copyMakeBorder(mat, dst, 10, 10, 10, 10, Core.BORDER_CONSTANT); 

    ArrayList<MatOfPoint> cnts = Tools.getContours(dst); 
    ArrayList<MatOfPoint2f> opened = new ArrayList<>(); 

    //convert to MatOfPoint2f to use approxPolyDP 
    for (MatOfPoint m : cnts) { 
     MatOfPoint2f temp = new MatOfPoint2f(m.toArray()); 
     opened.add(temp); 
     System.out.println("First loop runs"); 
    } 

    ArrayList<MatOfPoint> closed = new ArrayList<>(); 
    for (MatOfPoint2f conts : opened) { 
     MatOfPoint2f temp = new MatOfPoint2f(); 
     Imgproc.approxPolyDP(conts, temp, 3, true); 
     MatOfPoint closedTemp = new MatOfPoint(temp.toArray()); 
     closed.add(closedTemp); 
     System.out.println("Second loop runs"); 
    } 

    System.out.println("makeComplete: END"); 
    return closed; 
} 

А вот код Imgproc.convexHull()

public static ArrayList<MatOfPoint> getConvexHull(Mat mat) { 
    Mat dst = new Mat(); 
    Core.copyMakeBorder(mat, dst, 10, 10, 10, 10, Core.BORDER_CONSTANT); 

    ArrayList<MatOfPoint> cnts = Tools.getContours(dst); 
    ArrayList<MatOfPoint> out = new ArrayList<MatOfPoint>(); 
    MatOfPoint mopIn = cnts.get(0); 
    MatOfInt hull = new MatOfInt(); 
    Imgproc.convexHull(mopIn, hull, false); 

    MatOfPoint mopOut = new MatOfPoint(); 
    mopOut.create((int) hull.size().height, 1, CvType.CV_32SC2); 

    for (int i = 0; i < hull.size().height; i++) { 
     int index = (int) hull.get(i, 0)[0]; 
     double[] point = new double[]{ 
       mopIn.get(index, 0)[0], mopIn.get(index, 0)[1] 
     }; 
     mopOut.put(i, 0, point); 
    } 

    out.add(mopOut); 
    return out; 
} 

С наилучшими пожеланиями, Brk

ответ

0

Предполагая, что предположение правильно, что последняя строка (для столбца аналогична) не преобразуется (т.е. отсутствует), а затем попробуйте следующее. Предположим, что x идет слева направо и y сверху вниз. Мы добавляем одну строку пустых (белых?) Пикселей в нижней части изображения, а затем переходим слева направо. Ниже приведен псевдокод:

// EMPTY - value of backgroung e.g. white for the sample image 
PixelType curPixel = EMPTY; 
int y = height - 1; // last row, the one we added 
for (int x = 0; x < width; ++x) 
{ 
    // img(y,x) - current pixel, is "empty" 
    // img (y-1, x) - pixel above the current 
    if (img(y-1, x) != img(y, x)) 
    { 
     // pixel above isn't empty, so we make current pixel non-empty 
     img(y, x) = img(y-1, x); 
     // if we were drawing, then stop, otherwise - start 
     if (curPixel == EMPTY) 
      curPixel = img(y-1, x); 
     else 
      curPixel = EMPTY; 
    } 
    else 
    { 
     img(y, x) = curPixel; 
    } 
} 
Смежные вопросы