我正在开发一个需要对用手机相机拍摄的照片应用透视失真校正的应用程序。拍摄照片后,想法是将其显示在图像视图上,并让用户标记文档的四个角(一张卡片、一张纸等),然后根据这些点应用校正。这是我试图实现的一个例子:
http://1.bp.blogspot.com/-ro9hniPj52E/TkoM0kTlEnI/AAAAAAAAAbQ/c2R5VrgmC_w/s640/s4.jpg
关于如何在android上执行此操作的任何想法?
我正在开发一个需要对用手机相机拍摄的照片应用透视失真校正的应用程序。拍摄照片后,想法是将其显示在图像视图上,并让用户标记文档的四个角(一张卡片、一张纸等),然后根据这些点应用校正。这是我试图实现的一个例子:
http://1.bp.blogspot.com/-ro9hniPj52E/TkoM0kTlEnI/AAAAAAAAAbQ/c2R5VrgmC_w/s640/s4.jpg
关于如何在android上执行此操作的任何想法?
您不必为此使用库。您也可以将类的drawBitmap
函数之一与使用类函数Canvas
初始化的矩阵一起使用。setPolyToPoly
Matrix
public static Bitmap cornerPin(Bitmap b, float[] srcPoints, float[] dstPoints) {
int w = b.getWidth(), h = b.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas c = new Canvas(result);
Matrix m = new Matrix();
m.setPolyToPoly(srcPoints, 0, dstPoints, 0, 4);
c.drawBitmap(b, m, p);
return result;
}
(仅需要 Paint 对象来启用抗锯齿。)
用法:
int w = bitmap.getWidth(), h = bitmap.getHeight();
float[] src = {
0, 0, // Coordinate of top left point
0, h, // Coordinate of bottom left point
w, h, // Coordinate of bottom right point
w, 0 // Coordinate of top right point
};
float[] dst = {
0, 0, // Desired coordinate of top left point
0, h, // Desired coordinate of bottom left point
w, 0.8f * h, // Desired coordinate of bottom right point
w, 0.2f * h // Desired coordinate of top right point
};
Bitmap transformed = cornerPin(bitmap, src, dst);
其中src
是源点dst
的坐标,是目标点的坐标。结果:
你想做的事情有各种艺术名称,“角针”是视觉效果行业中常用的一种。您需要分两步进行:
原始图像的 4 个(非共线、透视失真)角和目标(未失真)图像的 4 个角定义了映射。这种映射称为“单应性” - 阅读指向的维基百科页面了解详细信息。一旦知道映射,就可以通过插值计算步骤(2)中的翘曲:对于目标图像中的每个像素,找到原始图像中的相应像素。由于这通常不会位于整数坐标处,因此您可以从邻居中插入其颜色。使用了各种插值方案,常见的是最近邻、双线性和双三次(在结果中按平滑度递增的顺序)。
对于 Android,我建议安装OpenCV SDK,然后使用几何变换例程(上述两个步骤的 getPerspectiveTransform 和 warpPerspective)。