Java 图像透视校正
我需要在3个轴(x,y和z)上旋转我的BuffereImage,旋转角度用3个整数表示。java中有任何本机方法吗?如果没有,我将如何实现这一目标 更新#1:我用OpenCV做了一些。。。完成后将更新 更新#2:因为这只是我项目的一部分,我意识到仅仅解决问题的一部分是不好的,所以我使用OpenCV getPerspectiveTransform()和Imgproc类中的warpPerspective()方法来转换图像。我基本上只是将代码移植到java,它工作得很好:) 此外,我还更改了线程名称,以使其符合实际问题/解决方案 代码(我使用OpenCV 3.1,因为它是最新版本):Java 图像透视校正,java,image-processing,bufferedimage,Java,Image Processing,Bufferedimage,我需要在3个轴(x,y和z)上旋转我的BuffereImage,旋转角度用3个整数表示。java中有任何本机方法吗?如果没有,我将如何实现这一目标 更新#1:我用OpenCV做了一些。。。完成后将更新 更新#2:因为这只是我项目的一部分,我意识到仅仅解决问题的一部分是不好的,所以我使用OpenCV getPerspectiveTransform()和Imgproc类中的warpPerspective()方法来转换图像。我基本上只是将代码移植到java,它工作得很好:) 此外,我还更改了线程名称,
导入java.awt.Graphics;
导入java.awt.image.buffereImage;
导入java.io.ByteArrayInputStream;
导入java.io.File;
导入java.io.IOException;
导入java.io.InputStream;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入org.opencv.core.core;
导入org.opencv.core.CvType;
导入org.opencv.core.Mat;
导入org.opencv.core.MatOfByte;
导入org.opencv.core.MatOfPoint2f;
导入org.opencv.core.Point;
导入org.opencv.imgproc.imgproc;
导入org.opencv.imgcodecs.imgcodecs;
公共类主框架{
私有静态最终长serialVersionUID=1L;
BuffereImage transformed=null;
//这些位置只是4个参考点的角。我正在写自动识别部分:)
点p4=新点(260,215);
点p1=新点(41221);
点p2=新点(46444);
点p3=新点(312435);
公用干管(){
System.loadLibrary(Core.NATIVE\u LIBRARY\u NAME);
文件f=新文件(“文件路径”);
MatOfPoint2f角点=新的MatOfPoint2f();
Mat src=Imgcodecs.imread(f.getAbsolutePath());
角落。推回(新的马托夫点2F(p1));
角落。推回(新的马托夫点2F(p2));
角落。推回(新的马托夫点2F(p3));
角落。推回(新的马托夫点2F(p4));
点中心=新点(0,0);
对于(int i=0;itop.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];
角。释放();
角落。推回(新的马托夫点2F(tl));
角落。推回(新的马托夫点2F(tr));
角落。推回(新的马托夫点2F(br));
角落。推回(新的马托夫点2F(bl));
System.out.println(corners.toArray()[0]+”、“+corners.toArray()[1]+”、“+corners.toArray()[2]+”、“+corners.toArray()[3]+”、”;
返回角;
}
公共缓冲区映像matToBufferedImage(Mat映像){
Mat image_tmp=图像;
MatOfByte MatOfByte=新MatOfByte();
Imgcodecs.imencode(“.jpg”,image_tmp,matOfByte);
字节[]byteArray=matOfByte.toArray();
buffereImage bufImage=null;
试一试{
InputStream in=新的ByteArrayInputStream(byteArray);
bufImage=ImageIO.read(in);
}捕获(例外e){
e、 printStackTrace();
}
返回bufImage;
}
}
我认为它可以满足您的要求,但我认为它不包含本机代码。发布您的尝试。我正在研究,但是,由于我缺乏数学知识,所以我不理解在研究过程中获得的任何信息。因此,你不是想让我们学习所需的数学,而是想让我们去做吗?我已经问过我的老师,但她拒绝帮助,因为她说我们将在两年内学习矩阵。此外,我还试图了解汗学院的课程,但不知何故,我缺乏知识,无法完全理解:(我投票结束这个问题,因为它从一个问题变成了另一个问题,现在不再包含任何问题。这是一个好答案,但我决定用OpenCV来做,因为我无论如何都需要它。
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;
}
}