[OpenCV Getting Started] Perspective Transformation


My personal blog: Mouren·Blog
WeChat public account: Mouren's sack
CSDN: Cao Mouren



Point2f class

An image is composed of pixels. In order to store each pixel, we usually use (x, y) coordinates in the Point class to represent it. Point2f means that the two data x and y of the Point class are of float type.
In order to process a certain area in the original image into a bird's-eye view, we first need to use Point2f to determine several points to frame the area to be processed. Here, we're going to treat a poker placed diagonally as a bird's-eye view. Therefore, four points are enough to determine its range.
Then create a Point2f class array to store the position in the new window of the processed bird's-eye view corresponding to the framed area of ​​the original picture. Corresponding code:

    Point2f srcPoint[4] = {
    
     {
    
    530,143},{
    
    773,193},{
    
    403,394}, {
    
    674,455} };//原图中框定四个点
    Point2f dstPoint[4] = {
    
     {
    
    0.0f,0.0f},{
    
    cardWidth,0.0f},{
    
    0.0f,cardHeight}, {
    
    cardWidth,cardHeight} };//分别对应鸟瞰图四个点

getPerspectiveTransform function

Function role: Obtain the matrix of image perspective transformation
according to the input and output points Overload 1:
Function definition:

Mat getPerspectiveTransform(
	const Point2f src[], 
	const Point2f dst[], 
	int solveMethod = DECOMP_LU
	);

Parameter explanation:

  • src[]: input point array
  • dst[]: output point array
  • solveMethod: passed to cv::solve(DecompTypes) to solve one or more linear system or least squares problems, DECOMP_LU is the default value. The relevant DecompTypes source code is (explanation attached in comments):
enum DecompTypes {
    
    
    /** Gaussian elimination with the optimal pivot element chosen. */
    DECOMP_LU       = 0,//最佳主轴元素的高斯消元法
    /** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix
    src1 can be singular */
    DECOMP_SVD      = 1,//奇异值分解(SVD)方法
    /** eigenvalue decomposition; the matrix src1 must be symmetrical */
    DECOMP_EIG      = 2,//特征值分解法
    /** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively
    defined */
    DECOMP_CHOLESKY = 3,//Cholesky分解法
    /** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */
    DECOMP_QR       = 4,//QR分解法
    /** while all the previous flags are mutually exclusive, this flag can be used together with
    any of the previous; it means that the normal equations
    \f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are
    solved instead of the original system
    \f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */
    DECOMP_NORMAL   = 16//使用正规方程公式,可以去前面的标志一起使用
};

Overloading two function definitions:

Mat getPerspectiveTransform(
	InputArray src, //输入图像
	InputArray dst, //输出图像
	int solveMethod = DECOMP_LU//同上
	);

warpPerspective function

Function role: perform perspective transformation on the image
Function definition:

void warpPerspective( 
	InputArray src, 
	OutputArray dst,
    InputArray M, 
    Size dsize,
    int flags = INTER_LINEAR,
    int borderMode = BORDER_CONSTANT,
    const Scalar& borderValue = Scalar()
    );

Parameter explanation:

  • src: Mat class, input image
  • dst: Mat class, output image after perspective transformation, the same data type as src
  • M: perspective transformation matrix
  • dsize: output image size
  • flags: interpolation method flag, source code:
enum InterpolationFlags{
    
    
    /** nearest neighbor interpolation */
    INTER_NEAREST        = 0,
    /** bilinear interpolation */
    INTER_LINEAR         = 1,
    /** bicubic interpolation */
    INTER_CUBIC          = 2,
    /** resampling using pixel area relation. It may be a preferred method for image decimation, as
    it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST
    method. */
    INTER_AREA           = 3,
    /** Lanczos interpolation over 8x8 neighborhood */
    INTER_LANCZOS4       = 4,
    /** Bit exact bilinear interpolation */
    INTER_LINEAR_EXACT = 5,
    /** Bit exact nearest neighbor interpolation. This will produce same results as
    the nearest neighbor method in PIL, scikit-image or Matlab. */
    INTER_NEAREST_EXACT  = 6,
    /** mask for interpolation codes */
    INTER_MAX            = 7,
    /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
    source image, they are set to zero */
    WARP_FILL_OUTLIERS   = 8,
    /** flag, inverse transformation

    For example, #linearPolar or #logPolar transforms:
    - flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$
    - flag is set: \f$dst(x,y) = src( \rho , \phi )\f$
    */
    WARP_INVERSE_MAP     = 16
};
  • borderMode: the flag of the pixel boundary extrapolation method, source code:
enum BorderTypes {
    
    
    BORDER_CONSTANT    = 0, //!< `iiiiii|abcdefgh|iiiiiii`  with some specified `i`
    BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
    BORDER_REFLECT     = 2, //!< `fedcba|abcdefgh|hgfedcb`
    BORDER_WRAP        = 3, //!< `cdefgh|abcdefgh|abcdefg`
    BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
    BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`

    BORDER_REFLECT101  = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_DEFAULT     = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
    BORDER_ISOLATED    = 16 //!< do not look outside of ROI
};
  • Scalar& borderValue: The color setting of the border, generally the default is 0

example

Purpose: To perform perspective transformation on the obliquely placed ♠K in the original image to obtain a bird's-eye view.
The original picture is as follows:

Source code:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#ifdef _DEBUG
#pragma comment(lib,"opencv_world453d.lib")
#else
#pragma comment(lib,"opencv_world453.lib")
#endif // _DEBUG

/********************将一张斜放的扑克牌生成鸟瞰图*********************/
int main()
{
    
    
    Mat transMatrix, imgOut;
    float cardWidth = 250;
    float cardHeight = 350;
    string path = "D:\\My Bags\\图片\\cards.jpg";
    Mat imgIn = imread(path);//读取原图像
    Point2f srcPoint[4] = {
    
     {
    
    530,143},{
    
    773,193},{
    
    403,394}, {
    
    674,455} };//原图中框定四个点
    Point2f dstPoint[4] = {
    
     {
    
    0.0f,0.0f},{
    
    cardWidth,0.0f},{
    
    0.0f,cardHeight}, {
    
    cardWidth,cardHeight} };//分别对应鸟瞰图四个点
    transMatrix = getPerspectiveTransform(srcPoint, dstPoint);//得到透视变换的矩阵
    warpPerspective(imgIn, imgOut, transMatrix, Size(cardWidth, cardHeight));//进行透视扭曲
    imshow("原图", imgIn);
    imshow("鸟瞰图", imgOut);
    waitKey(0);
    return 0;
}

Running result:
Original image
original image
♠K Aerial view:
Aerial View

Supongo que te gusta

Origin blog.csdn.net/ZBC010/article/details/120656248
Recomendado
Clasificación