opencv 透视变换作用在图上和点上的实现

原理介绍公式推导请参考下面这篇文章:

 https://blog.csdn.net/xiaowei_cqu/article/details/26471527

 

import cv2
import numpy as np
import matplotlib.pylab  as plt
img = cv2.imread('/home/aaron/Pictures/bird.jpeg')

pts1 = np.float32([[940,270],[1158,434],[386,872],[630,1028]])
pts2 = np.float32([[0,0],[300,0],[0,600],[300,600]])
M = cv2.getPerspectiveTransform(pts1,pts2)
plt.subplot(121),plt.imshow(img),plt.title('Input')
cv2.line(img,(988, 398),(1086, 456),(155,155,155),5)
p_key = np.float32([[[988, 398], [1086, 456]]])


p_key1 = cv2.perspectiveTransform(p_key, M) 

dst = cv2.warpPerspective(img,M,(300,600))

cv2.line(dst,(p_key1[0][0][0],p_key1[0][0][1]),(p_key1[0][1][0],p_key1[0][1][1]),(155,155,155),5)
print(p_key1)

plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

cv2.imwrite('/home/aaron/Pictures/bird1.jpeg', img)

cv2.imwrite('/home/aaron/Pictures/bird2.jpeg', dst)


k1 = [988, 398]
M = np.transpose(M)
x = (k1[0]*M[0][0]+k1[1]*M[1][0]+M[2][0])/(k1[0]*M[0][2]+k1[1]*M[1][2]+M[2][2])
y = (k1[0]*M[0][1]+k1[1]*M[1][1]+M[2][1])/(k1[0]*M[0][2]+k1[1]*M[1][2]+M[2][2])
print(x, y)

 首先根据对应的4个点对进行映射矩阵的求取.

M = cv2.getPerspectiveTransform(pts1,pts2)

关于全图的转换:

dst = cv2.warpPerspective(img,M,(300,600))

 

 

这里的关键点是选择的鸟的眼睛和嘴巴,下面进行了可视化变换前和变换后的效果.

关于关键点的变换方法有两种:

一种是通过透视变换的公式,代码中最后x,y的计算方法就是了.

 

一种是用opencv提供的函数:

p_key1 = cv2.perspectiveTransform(p_key, M) 

注意这里p_key的形式.是np.float32的np.array坐标,使用方法参考上述代码.

 

这里在补充一个c++版本的实验代码;

    cv::Mat src;
    cv::Size size(400,400);
    src.create(size, CV_MAKETYPE(0, 3));

    Point2f srcTri[4];//源图像点
    Point2f dstTri[4];//目标图像点
//源坐标
    srcTri[0] = Point2f(0, 0);//左上
    srcTri[1] = Point2f(400, 100);//右上
    srcTri[2] = Point2f(400, 300);//左下
    srcTri[3] = Point2f(0, 400);//右下
    //目标坐标
    dstTri[0] = Point2f(0, 0);
    dstTri[1] = Point2f(400, 0);
    dstTri[2] = Point2f(400, 400);
    dstTri[3] = Point2f(0, 400);

    cv::line(src, srcTri[0], srcTri[1], cv::Scalar(0, 255, 255), 5, 8, 0);
    cv::line(src, srcTri[1], srcTri[2], cv::Scalar(0, 255, 255), 5, 8, 0);
    cv::line(src, srcTri[2], srcTri[3], cv::Scalar(0, 255, 255), 5, 8, 0);
    cv::line(src, srcTri[3], srcTri[0], cv::Scalar(0, 255, 255), 5, 8, 0);
    cv::line(src, cv::Point(200,50), cv::Point(200,350), cv::Scalar(0, 255, 255), 5, 8, 0);

    cv::Mat dst;
    Mat transform = getPerspectiveTransform(srcTri, dstTri);
    warpPerspective(src, dst, transform, size);

    cv::Mat res;
    cv::Size size1(400,800);
    res.create(size1, CV_MAKETYPE(0, 3));
    cv::Mat img1 = res(cv::Rect(0,0,400,400));
    src.copyTo(img1);
    cv::Mat img2 = res(cv::Rect(0,400,400,400));
    dst.copyTo(img2);
    cv::imshow("show", res);
    cv::waitKey();

效果如图:上面的梯形变成下面的正方形,注意感觉透视变换的图像密度不均的表现。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中的代码是使用OpenCV库进行透视变换的示例代码。该代码首先读取一张名为"test.png"的图像,然后定义了变换前后的四个节坐标。接着使用getPerspectiveTransform函数获取变换矩阵,然后利用warpPerspective函数执行透视变换,并显示原图像变换后的图像。 引用\[2\]中的代码也是使用OpenCV库进行透视变换的示例代码。该代码首先读取一张名为"123.jpg"的图像,然后定义了变换前后的三个节坐标。接着使用getAffineTransform函数获取变换矩阵,然后利用warpAffine函数执行仿射变换,并显示原图像变换后的图像。 引用\[3\]中的代码同样是使用OpenCV库进行透视变换的示例代码。该代码首先读取一张名为"123.jpg"的图像,然后定义了变换前后的四个节坐标。接着使用getPerspectiveTransform函数获取变换矩阵,然后利用warpPerspective函数执行透视变换,并显示原图像变换后的图像。 综上所述,OpenCV库提供了多种函数用于实现透视变换,包括getPerspectiveTransform、warpPerspective和warpAffine等。这些函数可以根据给定的变换前后的节坐标来计算变换矩阵,并将图像进行相应的变换。 #### 引用[.reference_title] - *1* [基于OpenCV图像透视变换详解(从理论到实现再到实践)](https://blog.csdn.net/m0_51653200/article/details/127361624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【opencv】:图像透视变换](https://blog.csdn.net/weixin_44322778/article/details/129996366)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值