Java based on opencv - correct image

more, the images we get are not positive, and some will have a certain tilt, just like the Java基于opencv—矫正图像

below we have to turn them into the following Java基于opencv—矫正图像

We use the idea of ​​finding outlines to correct the picture; as long as there are obvious outlines, we can use this idea

concrete ideas: 1, first use the canny function provided by opencv to perform an edge detection 2. Then use the findContours function provided by opencv to find the outline of the image. From the middle result, find the largest outline, which is the outermost outline of our image. 3. After obtaining the final contour, calculate the angle between the rectangular contour and the horizontal, and then rotate the image. 4. Finally, we cut out the interest we are interested in from the rotated image, and we can

我实的它

First use the canny function provided by opencv to perform an edge detection; The function is no longer explained, Baidu is very much

/**
     * canny algorithm, edge detection
     *
     * @param src
     * @return
     */
    Public static Mat canny(Mat src) {
        Mat mat = src.clone();
        Imgproc.Canny(src, mat, 60, 200);
        HandleImgUtils.saveImg(mat , "C:/Users/admin/Desktop/opencv/open/x/canny.jpg");
        Return mat;
    }

Then use the findContours function provided by opencv to find the outline of the image, and find the largest outline from the middle result, which is the outermost outline of our image

/**
     * Returns the largest rectangle after edge detection and returns
     *
     * @param cannyMat
     * mat matrix after Canny
     * @return
     */
    Public static RotatedRect findMaxRect(Mat cannyMat) {

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat hierarchy = new Mat();

        // look for the outline
        Imgproc.findContours(cannyMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,
                New point(0, 0));

        // Find the largest contour that matches
        Double area = Imgproc.boundingRect(contours.get(0)).area();
        Int index = 0;

        // Find the largest contour that matches
        For (int i = 0; i < contours.size(); i++) {
            Double tempArea = Imgproc.boundingRect(contours.get(i)).area();
            If (tempArea > area) {
                Area = tempArea;
                Index = i;
            }
        }

        MatOfPoint2f matOfPoint2f = new MatOfPoint2f(contours.get(index).toArray());

        RotatedRect rect = Imgproc.minAreaRect(matOfPoint2f);

        Return rect;
    }

After getting the final outline, calculate the angle between the outline of the rectangle and the horizontal, then rotate the image

/**
     * Rotating rectangle
     *
     * @param src
     * mat matrix
     * @param rect
     * rectangle
     * @return
     */
    Public static Mat rotation(Mat cannyMat, RotatedRect rect) {
        // Get the four vertices of the rectangle
        Point[] rectPoint = new Point[4];
        Rect.points(rectPoint);

        Double angle = rect.angle + 90;

        Point center = rect.center;

        Mat CorrectImg = new Mat(cannyMat.size(), cannyMat.type());

        cannyMat.copyTo(CorrectImg);

        / / Get the rotation matrix operator
        Mat matrix = Imgproc.getRotationMatrix2D(center, angle, 0.8);

        Imgproc.warpAffine(CorrectImg, CorrectImg, matrix, CorrectImg.size(), 1, 0, new Scalar(0, 0, 0));

        Return CorrectImg;
    }

Finally, we cut out the interest we are interested in from the rotated image,

/**
     * Cut out the corrected image
     *
     * @param correctMat
     * Mat matrix after image correction
     */
    Public static void cutRect(Mat correctMat , Mat nativeCorrectMat) {
        // Get the largest rectangle
        RotatedRect rect = findMaxRect(correctMat);
        
        Point[] rectPoint = new Point[4];
        Rect.points(rectPoint);
        
        Int startLeft = (int)Math.abs(rectPoint[0].x);
        Int startUp = (int)Math.abs(rectPoint[0].y < rectPoint[1].y ? rectPoint[0].y : rectPoint[1].y);
        Int width = (int)Math.abs(rectPoint[2].x - rectPoint[0].x);
        Int height = (int)Math.abs(rectPoint[1].y - rectPoint[0].y);
        
        System.out.println("startLeft = " + startLeft);
        System.out.println("startUp = " + startUp);
        System.out.println("width = " + width);
        System.out.println("height = " + height);
        
        For(Point p : rectPoint) {
            System.out.println(p.x + " , " + p.y);
        }
        
        Mat temp = new Mat(nativeCorrectMat , new Rect(startLeft , startUp , width , height ));
        Mat t = new Mat();
        temp.copyTo(t);
        
        HandleImgUtils.saveImg(t , "C:/Users/admin/Desktop/opencv/open/x/cutRect.jpg");
    }

Integrate the whole process

/**
     * Correction image
     *
     * @param src
     * @return
     */
    Public static void correct(Mat src) {
        // Canny
        Mat cannyMat = canny(src);

        // Get the largest rectangle
        RotatedRect rect = findMaxRect(cannyMat);

        // rotate the rectangle
        Mat CorrectImg = rotation(cannyMat , rect);
        Mat NativeCorrectImg = rotation(src , rect);
        
        
        / / Crop rectangle
        cutRect(CorrectImg, NativeCorrectImg);
        
        HandleImgUtils.saveImg(src, "C:/Users/admin/Desktop/opencv/open/x/srcImg.jpg");

        HandleImgUtils.saveImg(CorrectImg, "C:/Users/admin/Desktop/opencv/open/x/correct.jpg");
    }

测试码

/**
     * Test corrected image
     */
    Public void testCorrect() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat src = HandleImgUtils.matFactory("C:/Users/admin/Desktop/opencv/open/x/x7.jpg");
        HandleImgUtils.correct(src);
    }

Java aspect of the opencv example is still very few, the code is written by their own reference blog, care less, please forgive me

http://www.cgpwyj.cn/ http://news.cgpwyj.cn/ http://item.cgpwyj.cn/ http://www.peacemind.com.cn/ http://news.peacemind.com.cn/ http://item.peacemind.com.cn/ http://www.tasknet.com.cn/ http://news.tasknet.com.cn/ http://item.tasknet.com.cn/ http://www.ownbar.cn/ http://news.ownbar.cn/ http://item.ownbar.cn http://www.shtarchao.net.cn/ http://news.shtarchao.net.cn/ http://item.shtarchao.net.cn/ http://www.metroworld.com.cn/ http://news.metroworld.com.cn/ http://item.metroworld.com.cn/ http://www.cngodo.cn/ http://news.cngodo.cn/ http://item.cngodo.cn/ http://www.gzrdbp.cn/ http://news.gzrdbp.cn/ http://item.gzrdbp.cn/ http://www.dnapt.cn/ http://news.dnapt.cn/ http://item.dnapt.cn/ http://www.ncxlk.cn/ http://news.ncxlk.cn/ http://item.ncxlk.cn/ http://www.zgxxyp.cn/ http://news.zgxxyp.cn/ http://item.zgxxyp.cn/ http://www.sjjdvr.cn/ http://news.sjjdvr.cn/ http://item.sjjdvr.cn/ http://www.sujinkeji.cn/ http://news.sujinkeji.cn/ http://item.sujinkeji.cn/ http://www.zsjxbd.cn/ http://news.zsjxbd.cn/ http://item.zsjxbd.cn/ http://www.yesgas.cn/ http://news.yesgas.cn/ http://item.yesgas.cn/ http://www.quickpass.sh.cn/ http://news.quickpass.sh.cn/ http://item.quickpass.sh.cn/ http://www.jspcrm.cn/ http://news.jspcrm.cn/ http://item.jspcrm.cn/ http://www.yjdwpt.cn/ http://news.yjdwpt.cn/ http://item.yjdwpt.cn/ http://www.henanwulian.cn/ http://news.henanwulian.cn/ http://item.henanwulian.cn/ http://www.hhrshh.cn/ http://news.hhrshh.cn/ http://item.hhrshh.cn/ http://www.gpgold.cn/ http://news.gpgold.cn/ http://item.gpgold.cn/ http://www.jingzhuiyou.cn/ http://news.jingzhuiyou.cn/ http://item.jingzhuiyou.cn/