透视变换通过投影的方式,把当前图像映射到另外一个平面,就像投影仪一样,如果幕布或者胶带其中任意一个与放映机发出的光纤不是垂直90度角的,那么投影到幕布上的图像就会发生畸变。这种畸变就是透视畸变的一种。
透视变换对畸变图像的校正需要取得畸变图像的 一组4个点的坐标, 和 目标图像的一组4个点的坐标, 通过两组坐标点可以计算出透视变换的变换矩阵,之后对整个原始图像执行变换矩阵的变换,就可以实现图像校正。
透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式如下:
也就是说:给定透视变换对应的四对像素点坐标,即可求得透视变换矩阵;反之,给定透视变换矩阵,即可对图像或像素点坐标完成透视变换
OpenCV提供了warpPerspective( )函数来实现图片的透视变换,只需要输入梯形四个顶点的坐标和目标画布四个角的坐标,即可自动完成转换。核心代码只有两行:首先读取两个坐标数组,计算变换矩阵;然后根据变换矩阵对原图进行透视变换,并输出到目标画布。
cv2.getPerspectiveTransform(src, dst) → retval
原图像的四个坐标顺序应与目标图像中的四个坐标一 一随影,若都是顺时针则都是顺时针,若都是 Z 字型,则都是 Z 字型。
返回由源图像中矩形到目标图像矩形变换的矩阵,得到矩阵得有用才行啊,所以引出下面这个函数
cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat srcImage = imread("C:\\Users\\LY\\Desktop\\FringeImage_2022-11-19-20-46\\2.bmp");//"C:\Users\LY\Desktop\FringeImage_2022-11-19-20-46\1.bmp"
// 目标图像
Mat dstImage;
// 取原图四个顶点up
//Point2f AffinePointsSrc[4] = { Point2f(729.4169,577.4854), Point2f(1341.8,608.1793),Point2f(724.1677,1108.8), Point2f(1340.7,1101.7) };
//down
Point2f AffinePointsSrc[4] = { Point2f(661.3996,770.9839), Point2f(1290.1,790.8698),Point2f(662.8568, 1311.7), Point2f(1285.3, 1290.6) };
//up
//Point2f AffinePointsDst[4] = { Point2f(923.902,612.663), Point2f(1567.42,635.797),Point2f(931.644,1188.41), Point2f(1571.4,1162.16) };
//down
Point2f AffinePointsDst[4] = { Point2f(923.435,609.981), Point2f(1567.35,632.982),Point2f(932.406,1185.72), Point2f(1571.48,1159.49) };
// 求出透视变换矩阵
Mat TransImage = getPerspectiveTransform(AffinePointsSrc, AffinePointsDst);
warpPerspective(srcImage, dstImage, TransImage, Size(srcImage.cols, srcImage.rows), 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);
imwrite("C:\\Users\\LY\\Desktop\\dst_down2.bmp",dstImage);
waitKey();
}