首页 / JAVA / java-图像的单应转换
java-图像的单应转换
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-图像的单应转换,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5760字,纯文字阅读大概需要9分钟。
内容图文
![java-图像的单应转换](/upload/InfoBanner/zyjiaocheng/664/172fe962151b42d6a0ce09591809c242.jpg)
这是我的示例图片
我想根据红色标记点对图像进行如下转换.
我实现了这里描述的公式:http://www.corrmap.com/features/homography_transformation.php
但是我的输出是:
输出图像中有太多黑色噪声.
这是我的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;
}
}
解决方法:
如beaker所述,
For each point in the original image you’re calculating its position in the destination image. That would miss a lot of points. It would be better to calculate the value of each pixel in the destination image interpolated from the original image.
为了避免这种情况,您可以为每个点使用向后映射(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;
}
}
要进一步了解,请参见this.
内容总结
以上是互联网集市为您收集整理的java-图像的单应转换全部内容,希望文章能够帮你解决java-图像的单应转换所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。