透视变换在图像还原的上的应用很广泛,他是将成像投影到一个新的视平面。比如两个摄像头在不同的角度对统一物体进行拍照,物体上的同一个点在两张照片上的坐标是不一样的,为了实现两张图片同一个点的对应关系映射,透视变换就实现了此功能。
一、获取透视变换矩阵函数GetPerspectiveTransform
1、从四对对应的点计算透视变换.
函数计算的是 3*3的满足以下关系的透视转换矩阵:
CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
参数 src 源图像四边形顶点坐标.
参数 dst 目标图像对应的四边形顶点坐标.
参数 solveMethod 传递给cv::solve(#DecompTypes)的计算方法,默认是DECOMP_LU
2、初始区域的四个点和结束区域的四个点的顺序必须是:左上、右上、左下、右下。
3、这四个点可以是Mat矩阵 也可以是Point2f数组、vector<Point2f>。数据类型必须是float
二、透视变换函数warpPerspective
通过透视矩阵把透视变换应用到一个图像上。
如果指定 CV_WARP_INVERSE_MAP,函数warpPerspective使用下面指定矩阵转换源图像:
否则,转换首先使用反转进行反转,然后代替M放到上面的公式中,这个函数不能使用in-place(就地)操作。
原型
CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
参数:src 输入图像。
参数: dst 输出图像,具有Size dsize并且和源图像具有相同的类型 .
参数: M 3*3的转换矩阵.
参数: dsize 输出图像的大小.
参数: flags 插值方法的组合 如果要缩小图像,推荐使用INTER_AREA插值效果最好,如果要放大图像,INTER_CUBIC效果最好,但是速度较慢,可以考虑使用INTER_LINEAR速度较快,效果也还不错参考
CV_WARP_FILL_OUTLIERS - 填充所有输出图像的象素。如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval. CV_WARP_INVERSE_MAP - 指定 map_matrix 是输出图像到输入图像的反变换,因此可以直接用来做象素插值。否则, 函数从 map_matrix 得到反变换。
参数: borderMode 像素外推方法 (#BORDER_CONSTANT指定常数填充 or #BORDER_REPLICATE复制边缘像素填充).
参数: borderValue 固定边缘情况下使用的值,缺省是0.
void myCV::perspectivetest()
{
Mat src = imread("06.jpg");
//Mat a1 = (Mat_<float>(4, 2) << 187, 230, 1123, 230, 17, 1680, 1309, 1680);
//Mat a2 = (Mat_<float>(4, 2) << 0, 0, 1292, 0, 0, 1450, 1292, 1450);
Point2f a3[4] = { {187, 230}, {1123, 230}, {17, 1680}, {1309, 1680 } };
Point2f a4[4] = { { 0, 0}, {1292, 0}, {0, 1450}, {1292, 1450} };
Mat dst, m = getPerspectiveTransform(a3, a4, 0);
warpPerspective(src, dst, m, Size(1292, 1450));
namedWindow("dst", WINDOW_FREERATIO);
imshow("dst", dst);
}