Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 图像的单应变换_Java_Image Processing_Homography - Fatal编程技术网

Java 图像的单应变换

Java 图像的单应变换,java,image-processing,homography,Java,Image Processing,Homography,这是我的示例图像 我想根据红色标记点对图像进行如下变换 我实现了这里描述的公式: 但我的输出是: 输出图像中有太多的黑噪声。 这是我的java代码 import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import Jama.Matrix; import java.io.File; import javax.imageio.ImageIO; public c

这是我的示例图像

我想根据红色标记点对图像进行如下变换

我实现了这里描述的公式:

但我的输出是:

输出图像中有太多的黑噪声。 这是我的java代码

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import Jama.Matrix;
import java.io.File;
import javax.imageio.ImageIO;

public class ImageWarp {
        private double x1, y1, x2, y2, x3, y3, x4, y4, X1, Y1, X2, Y2, X3, Y3, X4,
                        Y4;

        public static void main(String[] args) throws IOException {
            ImageWarp iw = new ImageWarp();

            BufferedImage img = ImageIO.read(new File("C:\\Users\\mohar\\Documents\\NetBeansProjects\\Test3\\src\\notebook.jpg"));
            ArrayList<Coordinate> coords = new ArrayList<>();
            coords.add(new Coordinate(39, 206));
            coords.add(new Coordinate(218, 29));
            coords.add(new Coordinate(541, 153));
            coords.add(new Coordinate(417, 417));

            BufferedImage output = iw.getCropedImage(img, coords, 500, 500);
            ImageIO.write(output, "jpg", new File("C:\\Users\\mohar\\Documents\\NetBeansProjects\\Test3\\src\\output.jpg"));
        }

        public BufferedImage getCropedImage(BufferedImage imgBuffer,
                        ArrayList<Coordinate> cornersCordinate, int imageWidth,
                        int imageHeight) throws IOException {

                x1 = Math.abs(cornersCordinate.get(0).getX());
                y1 = Math.abs(cornersCordinate.get(0).getY());
                x2 = Math.abs(cornersCordinate.get(1).getX());
                y2 = Math.abs(cornersCordinate.get(1).getY());
                x3 = Math.abs(cornersCordinate.get(2).getX());
                y3 = Math.abs(cornersCordinate.get(2).getY());
                x4 = Math.abs(cornersCordinate.get(3).getX());
                y4 = Math.abs(cornersCordinate.get(3).getY());
                X1 = 0;
                Y1 = 0;
                X2 = imageWidth - 1;
                Y2 = 0;
                X3 = imageWidth - 1;
                Y3 = imageHeight - 1;
                X4 = 0;
                Y4 = imageHeight - 1;

                double M_a[][] = { { x1, y1, 1, 0, 0, 0, -x1 * X1, -y1 * X1 },
                                { x2, y2, 1, 0, 0, 0, -x2 * X2, -y2 * X2 },
                                { x3, y3, 1, 0, 0, 0, -x3 * X3, -y3 * X3 },
                                { x4, y4, 1, 0, 0, 0, -x4 * X4, -y4 * X4 },
                                { 0, 0, 0, x1, y1, 1, -x1 * Y1, -y1 * Y1 },
                                { 0, 0, 0, x2, y2, 1, -x2 * Y2, -y2 * Y2 },
                                { 0, 0, 0, x3, y3, 1, -x3 * Y3, -y3 * Y3 },
                                { 0, 0, 0, x4, y4, 1, -x4 * Y4, -y4 * Y4 }, };

                double M_b[][] = { { X1 }, { X2 }, { X3 }, { X4 }, { Y1 }, { Y2 },
                                { Y3 }, { Y4 }, };

                Matrix A = new Matrix(M_a);
                Matrix B = new Matrix(M_b);
                Matrix C = A.solve(B);
                double a = C.get(0, 0);
                double b = C.get(1, 0);
                double c = C.get(2, 0);
                double d = C.get(3, 0);
                double e = C.get(4, 0);
                double f = C.get(5, 0);
                double g = C.get(6, 0);
                double h = C.get(7, 0);

                int width = imgBuffer.getWidth();
                int height = imgBuffer.getHeight();

                BufferedImage output = new BufferedImage(imageWidth, imageHeight,
                                BufferedImage.TYPE_INT_RGB);
                for (int i = 0; i < width; i++) {
                        for (int j = 0; j < height; j++) {
                                if (isInside(i, j)) {
                                        int x = (int) (((a * i) + (b * j) + c) / ((g * i) + (h * j) + 1));
                                        int y = (int) (((d * i) + (e * j) + f) / ((g * i) + (h * j) + 1));
                                        int p = imgBuffer.getRGB(i, j);
                                        output.setRGB(x, y, p);
                                }
                        }
                }

                return output;
        }

        private boolean isInside(int x, int y) {

                double apd = Math.abs(0.5 * (x1 * y + x * y4 + x4 * y1 - x * y1 - x4
                                * y - x1 * y4));
                double dpc = Math.abs(0.5 * (x4 * y + x * y3 + x3 * y4 - x * y4 - x3
                                * y - x4 * y3));
                double cpb = Math.abs(0.5 * (x3 * y + x * y2 + x2 * y3 - x * y3 - x2
                                * y - x3 * y2));
                double pba = Math.abs(0.5 * (x * y2 + x2 * y1 + x1 * y - x2 * y - x1
                                * y2 - x * y1));
                double rec = Math.abs(0.5 * (x1 * y2 + x2 * y3 + x3 * y4 + x4 * y1 - x2
                                * y1 - x3 * y2 - x4 * y3 - x1 * y4));

                if ((apd + dpc + cpb + pba) > rec) {
                        return false;
                } else {
                        return true;
                }
        }

}

class Coordinate {
    private double x;
    private double y;

    public Coordinate(double x, double y) {
        this.x = x;
        this.y = y;
    }



    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }


}
导入java.awt.image.buffereImage;
导入java.io.IOException;
导入java.util.ArrayList;
导入Jama.Matrix;
导入java.io.File;
导入javax.imageio.imageio;
公共类ImageWarp{
专用双x1,y1,x2,y2,x3,y3,x4,y4,x1,y1,x2,y2,x3,y3,x4,
Y4;
公共静态void main(字符串[]args)引发IOException{
ImageWarp iw=新ImageWarp();
BuffereImage img=ImageIO.read(新文件(“C:\\Users\\mohar\\Documents\\NetBeansProjects\\Test3\\src\\notebook.jpg”);
ArrayList coords=新的ArrayList();
添加(新坐标(39206));
坐标添加(新坐标(218,29));
坐标添加(新坐标(541153));
添加(新坐标(417417));
BuffereImage输出=iw.GetCropImage(img,coords,500500);
write(输出,“jpg”,新文件(“C:\\Users\\mohar\\Documents\\NetBeansProjects\\Test3\\src\\output.jpg”);
}
公共缓冲区映像getCropedImage(缓冲区映像imgBuffer,
ArrayList cornersCordinate,int imageWidth,
int imageHeight)引发IOException{
x1=Math.abs(cornerscodinate.get(0.getX());
y1=Math.abs(cornersCordinate.get(0.getY());
x2=Math.abs(cornersCordinate.get(1.getX());
y2=Math.abs(cornersCordinate.get(1.getY());
x3=Math.abs(cornersCordinate.get(2.getX());
y3=Math.abs(cornersCordinate.get(2.getY());
x4=Math.abs(cornersCordinate.get(3.getX());
y4=Math.abs(cornersCordinate.get(3.getY());
X1=0;
Y1=0;
X2=图像宽度-1;
Y2=0;
X3=图像宽度-1;
Y3=图像高度-1;
X4=0;
Y4=图像高度-1;
双M_a[][]={{{x1,y1,1,0,0,0,-x1*x1,-y1*x1},
{x2,y2,1,0,0,0,-x2*x2,-y2*x2},
{x3,y3,1,0,0,0,-x3*x3,-y3*x3},
{x4,y4,1,0,0,0,-x4*x4,-y4*x4},
{0,0,0,x1,y1,1,-x1*y1,-y1*y1},
{0,0,0,x2,y2,1,-x2*y2,-y2*y2},
{0,0,0,x3,y3,1,-x3*y3,-y3*y3},
{0,0,0,x4,y4,1,-x4*y4,-y4*y4},};
双M_b[]]={{X1}、{X2}、{X3}、{X4}、{Y1}、{Y2},
{Y3},{Y4},};
矩阵A=新矩阵(M_A);
矩阵B=新矩阵(M_B);
矩阵C=A.解(B);
双a=C.get(0,0);
双b=C.get(1,0);
双c=c.get(2,0);
双d=C.get(3,0);
双e=C.get(4,0);
双f=C.get(5,0);
双g=C.get(6,0);
双h=C.get(7,0);
int width=imgBuffer.getWidth();
int height=imgBuffer.getHeight();
BuffereImage输出=新的BuffereImage(图像宽度、图像高度、,
BuffereImage.TYPE_INT_RGB);
对于(int i=0;irec){
返回false;
}否则{
返回true;
}
}
}
类坐标{
私人双x;
私人双y;
公共坐标(双x,双y){
这个.x=x;
这个。y=y;
}
公共双getX(){
返回x;
}
公共双盖{
返回y;
}
}
如所述

对于原始图像中的每个点,您正在计算其在目标图像中的位置。那会错过很多要点。最好计算从原始图像插值的目标图像中每个像素的值

为了避免这种情况,可以对每个点使用向后映射
(x',y')
(x,y)

这是你修改过的可行代码

public class ImageWarp {
    private double x1, y1, x2, y2, x3, y3, x4, y4, X1, Y1, X2, Y2, X3, Y3, X4,
            Y4;

    public BufferedImage getCropedImage(BufferedImage imgBuffer,
            ArrayList<Coordinate> cornersCordinate, int imageWidth,
            int imageHeight) throws IOException {

        X1 = Math.abs(cornersCordinate.get(0).getX());
        Y1 = Math.abs(cornersCordinate.get(0).getY());
        X2 = Math.abs(cornersCordinate.get(1).getX());
        Y2 = Math.abs(cornersCordinate.get(1).getY());
        X3 = Math.abs(cornersCordinate.get(2).getX());
        Y3 = Math.abs(cornersCordinate.get(2).getY());
        X4 = Math.abs(cornersCordinate.get(3).getX());
        Y4 = Math.abs(cornersCordinate.get(3).getY());
        x1 = 0;
        y1 = 0;
        x2 = imageWidth - 1;
        y2 = 0;
        x3 = imageWidth - 1;
        y3 = imageHeight - 1;
        x4 = 0;
        y4 = imageHeight - 1;

        double M_a[][] = { { x1, y1, 1, 0, 0, 0, -x1 * X1, -y1 * X1 },
                { x2, y2, 1, 0, 0, 0, -x2 * X2, -y2 * X2 },
                { x3, y3, 1, 0, 0, 0, -x3 * X3, -y3 * X3 },
                { x4, y4, 1, 0, 0, 0, -x4 * X4, -y4 * X4 },
                { 0, 0, 0, x1, y1, 1, -x1 * Y1, -y1 * Y1 },
                { 0, 0, 0, x2, y2, 1, -x2 * Y2, -y2 * Y2 },
                { 0, 0, 0, x3, y3, 1, -x3 * Y3, -y3 * Y3 },
                { 0, 0, 0, x4, y4, 1, -x4 * Y4, -y4 * Y4 }, };

        double M_b[][] = { { X1 }, { X2 }, { X3 }, { X4 }, { Y1 }, { Y2 },
                { Y3 }, { Y4 }, };

        Matrix A = new Matrix(M_a);
        Matrix B = new Matrix(M_b);
        Matrix C = A.solve(B);
        double a = C.get(0, 0);
        double b = C.get(1, 0);
        double c = C.get(2, 0);
        double d = C.get(3, 0);
        double e = C.get(4, 0);
        double f = C.get(5, 0);
        double g = C.get(6, 0);
        double h = C.get(7, 0);


        BufferedImage output = new BufferedImage(imageWidth, imageHeight,
                BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < imageWidth; i++) {
            for (int j = 0; j < imageHeight; j++) {
                    int x = (int) (((a * i) + (b * j) + c) / ((g * i) + (h * j) + 1));
                    int y = (int) (((d * i) + (e * j) + f) / ((g * i) + (h * j) + 1));
                    int p = imgBuffer.getRGB(x, y);
                    output.setRGB(i, j, p);
            }
        }

        return output;
    }
}