Bootstrap

OpenCV代码提取 warpPerspective函数的实现

               

 For perspective transformation, you need a 3x3 transformation matrix. Straight lines will remain straight even after the transformation. To find this transformation matrix, you need 4 points on the input image and corresponding points on the output image. Among these 4 points,3 of them should not be collinear.

 透视变换(perspective transformation)是将图像投影到一个新的视平面,也称为投影映射。

         公式:dst(x,y) = src((M11x+M12y+M13)/(M31x+M32y+M33), (M21x+M22y+M23)/(M31x+M32y+M33))

 仿射变换与透视变换的区别:

 (1)、仿射变换,它可以将矩形转换成平行四边形,也可以将矩形的边压扁但必须保持边是平行的,也可以将矩形旋转或者按比例缩放。透视变换除了能够处理仿射变换的操作外,还可以将矩形转换成梯形。即仿射变换后还是平行四边形,透视变换后是四边形。因此可以说仿射变换是透视变换的一个子集。

         (2)、在OpenCV中,基于2*3矩阵进行的变换,是图像的仿射变换;基于3*3矩阵进行的变换,是图像的透视变换或者单应性映射。图像透视变换多用于图像校正

         下图是截取的《Learning OpenCV》一书中的插图:


 目前支持uchar和float两种类型,经测试,与OpenCV3.1结果完全一致。

 实现代码warpPerspective.hpp:

// fbc_cv is free software and uses the same licence as OpenCV// Email: [email protected]#ifndef FBC_CV_WARP_PERSPECTIVE_HPP_#define FBC_CV_WARP_PERSPECTIVE_HPP_/* reference: include/opencv2/imgproc.hpp              modules/imgproc/src/imgwarp.cpp*/#include <typeinfo>#include "core/mat.hpp"#include "core/invert.hpp"#include "imgproc.hpp"#include "remap.hpp"namespace fbc {
   // Calculates a perspective transform from four pairs of the corresponding pointsFBC_EXPORTS int getPerspectiveTransform(const Point2f src1[], const Point2f src2[], Mat_<double, 1>& dst);// Applies a perspective transformation to an image// The function cannot operate in - place// support type: uchar/float/* \f[\texttt{ dst } (x, y) = \texttt{ src } \left(\frac{ M_{ 11 } x + M_{ 12 } y + M_{ 13 } }{M_{ 31 } x + M_{ 32 } y + M_{ 33 }}, \frac{ M_{ 21 } x + M_{ 22 } y + M_{ 23 } }{M_{ 31 } x + M_{ 32 } y + M_{ 33 }} \right)\f]*/template<typename _Tp1, typename _Tp2, int chs1, int chs2>int warpPerspective(const Mat_<_Tp1, chs1>& src, Mat_<_Tp1, chs1>& dst, const Mat_<_Tp2, chs2>& M_, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar()){ FBC_Assert(src.data != NULL && dst.data != NULL && M_.data != NULL); FBC_Assert(src.cols > 0 && src.rows > 0 && dst.cols > 0 && dst.rows > 0); FBC_Assert(src.data != dst.data); FBC_Assert(typeid(double).name() == typeid(_Tp2).name() && M_.rows == 3 && M_.cols == 3); FBC_Assert((typeid(uchar).name() == typeid(_Tp1).name()) || (typeid(float).name() == typeid(_Tp1).name())); // uchar/float double M[9]; Mat_<double, 1> matM(3, 3, M); int interpolation = flags & INTER_MAX; if (interpolation == INTER_AREA)  interpolation = INTER_LINEAR; if (!(flags & WARP_INVERSE_MAP))  invert(M_, matM);
;