图像透视校正 [英] Image perspective correction

查看:167
本文介绍了图像透视校正的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在3轴(x,y和z)上旋转我的BufferedImage,以3个整数给出的角度。 java中有任何本机方法吗?如果没有,我将如何实现?

更新#1:我已经使用OpenCV做了一些...完成后会更新!

Update #1: I've done some of it with OpenCV... Will update when finished!

更新#2:由于这只是我项目的一部分,我意识到解决问题的一部分并不好,所以我使用了OpenCV getPerspectiveTransform( )然后从Imgproc类转换图像的warpPerspective()方法。我基本上只是将这个代码移植到java和它工作正常:))

Update #2: Since this was just a part of my project, I realized that solving just a part of the problem wouldn't be good, so I used OpenCV getPerspectiveTransform() and then warpPerspective() methods from Imgproc class to transform image. I have basically just ported this code to java and it works fine :)

此外,由于更改,我更改了线程名称,使其适合实际的问题/解决方案。

Also I have changed the thread name due the changes to make it fit the actual question/solution.

代码(我使用OpenCV 3.1,因为它是最新版本):

Code (I used OpenCV 3.1, since it's the latest version):

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;

public class Main extends JFrame {
    private static final long serialVersionUID = 1L;

    BufferedImage transformed = null;

    //These locations are just the corners of the 4 reference points. I am writing the auto recognition part right now :)
    Point p4 = new Point(260, 215);
    Point p1 = new Point(412, 221);
    Point p2 = new Point(464, 444);
    Point p3 = new Point(312, 435);

    public Main() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        File f = new File("FILEPATH ");

        MatOfPoint2f corners = new MatOfPoint2f();

        Mat src = Imgcodecs.imread(f.getAbsolutePath());

        corners.push_back(new MatOfPoint2f(p1));
        corners.push_back(new MatOfPoint2f(p2));
        corners.push_back(new MatOfPoint2f(p3));
        corners.push_back(new MatOfPoint2f(p4));

        Point center = new Point(0, 0);
        for (int i = 0; i < corners.toArray().length; i++) {
            center.x += corners.toArray()[i].x;
            center.y += corners.toArray()[i].y;
        }

        center.x /= corners.toArray().length;
        center.y /= corners.toArray().length;
        sortCorners(corners, center);

        Mat quad = Mat.zeros(1000, 1900, CvType.CV_8U);

        MatOfPoint2f quad_pts = new MatOfPoint2f();

        quad_pts.push_back(new MatOfPoint2f(new Point(0, 0)));
        quad_pts.push_back(new MatOfPoint2f(new Point(quad.width(), 0)));
        quad_pts.push_back(new MatOfPoint2f(new Point(quad.width(), quad.height())));
        quad_pts.push_back(new MatOfPoint2f(new Point(0, quad.height())));

        Mat transmtx = Imgproc.getPerspectiveTransform(corners, quad_pts);

        Imgproc.warpPerspective(src, quad, transmtx, quad.size());

        transformed = matToBufferedImage(quad);

        setSize(500, 500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void paint(Graphics g) {
        g.clearRect(0, 0, this.getWidth(), this.getHeight());
        g.drawImage(transformed, 0, 22, null);
    }

    public MatOfPoint2f sortCorners(MatOfPoint2f corners, Point center) {
        MatOfPoint2f top = new MatOfPoint2f();
        MatOfPoint2f bot = new MatOfPoint2f();

        for (int i = 0; i < corners.toArray().length; i++) {
            if (corners.toArray()[i].y < center.y){
                top.push_back(new MatOfPoint2f(corners.toArray()[i]));
            }
            else
                bot.push_back(new MatOfPoint2f(corners.toArray()[i]));
        }

        Point tl = p4;
        Point tr = p1;
        Point bl = p2;
        Point br = p3;

        tl = top.toArray()[0].x > top.toArray()[1].x ? top.toArray()[1] : top.toArray()[0];
        tr = top.toArray()[0].x > top.toArray()[1].x ? top.toArray()[0] : top.toArray()[1];
        bl = bot.toArray()[0].x > bot.toArray()[1].x ? bot.toArray()[1] : bot.toArray()[0];
        br = bot.toArray()[0].x > bot.toArray()[1].x ? bot.toArray()[0] : bot.toArray()[1];

        corners.release();
        corners.push_back(new MatOfPoint2f(tl));
        corners.push_back(new MatOfPoint2f(tr));
        corners.push_back(new MatOfPoint2f(br));
        corners.push_back(new MatOfPoint2f(bl));
        System.out.println(corners.toArray()[0] + ", " + corners.toArray()[1] + ", " + corners.toArray()[2] + ", " + corners.toArray()[3] + ", ");
        return corners;

    }

    public BufferedImage matToBufferedImage(Mat image) {
        Mat image_tmp = image;
        MatOfByte matOfByte = new MatOfByte();

        Imgcodecs.imencode(".jpg", image_tmp, matOfByte);

        byte[] byteArray = matOfByte.toArray();
        BufferedImage bufImage = null;

        try {

            InputStream in = new ByteArrayInputStream(byteArray);
            bufImage = ImageIO.read(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufImage;
    }
}


推荐答案

我认为 TransformJ软件包可以满足您的需求,但我认为它不包含本地代码。

I think that the TransformJ package does what you want, but I don't think it contains native code.

这篇关于图像透视校正的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆