opencv透视变换:GetPerspectiveTransform、warpPerspective函数的使用

 

透视变换在图像还原的上的应用很广泛,他是将成像投影到一个新的视平面。比如两个摄像头在不同的角度对统一物体进行拍照,物体上的同一个点在两张照片上的坐标是不一样的,为了实现两张图片同一个点的对应关系映射,透视变换就实现了此功能。

一、获取透视变换矩阵函数GetPerspectiveTransform

功能描述

从四对对应的点计算透视变换.函数计算的是 3*3的满足以下关系的透视转换矩阵:

\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map\_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}

此处

dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,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

  • 参考 findHomography, warpPerspective, perspectiveTransform

二、透视变换函数warpPerspective

功能描述

通过透视矩阵把透视变换应用到一个图像上。

如果指定 CV_WARP_INVERSE_MAP,函数warpPerspective使用下面指定矩阵转换源图像:

\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 )

否则,转换首先使用反转进行反转,然后代替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_LINEAR(双线性插值)或 INTER_NEAREST(双线性插值))和可选的标志g #WARP_INVERSE_MAP, 为了设置M作为反转转换 (dst->src)

  • 参数: borderMode 像素外推方法 (#BORDER_CONSTANT指定常数填充 or #BORDER_REPLICATE复制边缘像素填充).

  • 参数: borderValue 固定边缘情况下使用的值,缺省是0.

  • 参考warpAffine, resize, remap, getRectSubPix, perspectiveTransform

源码示例:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc_c.h>
​
using namespace cv;
int main()
{
    // 源图像
    Mat srcImage = imread("D:\\OpenCVtest\\images\\juice.png");
    // 目标图像
    Mat dstImage;
    
    // 取原图四个顶点
    Point2f AffinePointsSrc[4] = { Point2f(40, 50), Point2f(100, 190), Point2f(200, 50), Point2f(300, 190) };
    // 取原图四个顶点在目标图像上的坐标
    Point2f AffinePointsDst[4] = { Point2f(50, 60), Point2f(120, 200), Point2f(200, 50), Point2f(300, 190) };
​
​
    // 求出透视变换矩阵
    Mat TransImage = getPerspectiveTransform(AffinePointsSrc, AffinePointsDst);
​
    warpPerspective(srcImage, dstImage, TransImage, Size(srcImage.cols, srcImage.rows), CV_INTER_CUBIC);
​
    // 目标图像上的四个点上标记圆形
    for (int i = 0; i < 4; i++)
    {
        circle(dstImage, AffinePointsDst[i], 2, Scalar(0, 0, 255), 2);
    }
    
    imshow("src", srcImage);
    imshow("dst", dstImage);
    waitKey();
}

运行结果

猜你喜欢

转载自blog.csdn.net/jndingxin/article/details/109335687