Обрезка изображения с контуром - PullRequest
0 голосов
/ 14 сентября 2018

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

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Преобразование изображения в оттенки серого.

Порог изображения для снижения шума.

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

В коде pythonбудет выглядеть так:

import cv2
import numpy as np

img = cv2.imread('table.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 222, 255, cv2.THRESH_BINARY )
# write out the thresholded image to debug the 222 value    
cv2.imwrite("thresh.png", thresh)

indices = np.where(thresh != 255)
coords = np.array([(b,a) for a, b in zip(*(indices[0], indices[1]))])
# coords = cv2.convexHull(coords)
rect = cv2.minAreaRect(coords) 
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
cv2.imwrite("box.png", img)  

Для меня это дает следующее изображение.enter image description here

Если ваше изображение не имеет красных квадратов, оно будет более плотным.

0 голосов
/ 14 сентября 2018

Используйте грубое преобразование, чтобы найти линии на изображении.

OpenCV может легко это сделать и имеет привязки Java. Смотрите учебник на этой странице о том, как сделать что-то очень похожее.

https://docs.opencv.org/3.4.1/d9/db0/tutorial_hough_lines.html

Вот код Java, приведенный в руководстве:

import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class HoughLinesRun {
    public void run(String[] args) {
        // Declare the output variables
        Mat dst = new Mat(), cdst = new Mat(), cdstP;
        String default_file = "../../../../data/sudoku.png";
        String filename = ((args.length > 0) ? args[0] : default_file);
        // Load an image
        Mat src = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
        // Check if image is loaded fine
        if( src.empty() ) {
            System.out.println("Error opening image!");
            System.out.println("Program Arguments: [image_name -- default "
                    + default_file +"] \n");
            System.exit(-1);
        }
        // Edge detection
        Imgproc.Canny(src, dst, 50, 200, 3, false);
        // Copy edges to the images that will display the results in BGR
        Imgproc.cvtColor(dst, cdst, Imgproc.COLOR_GRAY2BGR);
        cdstP = cdst.clone();
        // Standard Hough Line Transform
        Mat lines = new Mat(); // will hold the results of the detection
        Imgproc.HoughLines(dst, lines, 1, Math.PI/180, 150); // runs the actual detection
        // Draw the lines
        for (int x = 0; x < lines.rows(); x++) {
            double rho = lines.get(x, 0)[0],
                    theta = lines.get(x, 0)[1];
            double a = Math.cos(theta), b = Math.sin(theta);
            double x0 = a*rho, y0 = b*rho;
            Point pt1 = new Point(Math.round(x0 + 1000*(-b)), Math.round(y0 + 1000*(a)));
            Point pt2 = new Point(Math.round(x0 - 1000*(-b)), Math.round(y0 - 1000*(a)));
            Imgproc.line(cdst, pt1, pt2, new Scalar(0, 0, 255), 3, Imgproc.LINE_AA, 0);
        }
        // Probabilistic Line Transform
        Mat linesP = new Mat(); // will hold the results of the detection
        Imgproc.HoughLinesP(dst, linesP, 1, Math.PI/180, 50, 50, 10); // runs the actual detection
        // Draw the lines
        for (int x = 0; x < linesP.rows(); x++) {
            double[] l = linesP.get(x, 0);
            Imgproc.line(cdstP, new Point(l[0], l[1]), new Point(l[2], l[3]), new Scalar(0, 0, 255), 3, Imgproc.LINE_AA, 0);
        }
        // Show results
        HighGui.imshow("Source", src);
        HighGui.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst);
        HighGui.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP);
        // Wait and Exit
        HighGui.waitKey();
        System.exit(0);
    }
}
public class HoughLines {
    public static void main(String[] args) {
        // Load the native library.
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        new HoughLinesRun().run(args);
    }
}

Lines или LinesP будут содержать найденные строки. Вместо того, чтобы рисовать их (как в примере), вы захотите манипулировать ими немного дальше.

Сортировка найденных линий по наклону.

Два самых больших кластера будут горизонтальными линиями, а затем вертикальными.
Для горизонтальных линий рассчитайте и сортируйте по точке пересечения y. Наибольший перехват y описывает верхнюю часть таблицы. Наименьший перехват у - это нижняя часть таблицы.

Для вертикальных линий рассчитать и отсортировать по перехвату х. Наибольший x перехват - правая сторона таблицы. Наименьший x-перехват - левая сторона таблицы.

Теперь у вас есть координаты четырех углов стола, и вы можете выполнять стандартные операции с изображениями для кадрирования / поворота и т. Д. OpenCV может помочь вам и в этом шаге.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...