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 透视变换作用在图上和点上的实现_第1张图片

 

一种是用opencv提供的函数:

p_key1 = cv2.perspectiveTransform(p_key, M) 

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

opencv 透视变换作用在图上和点上的实现_第2张图片

opencv 透视变换作用在图上和点上的实现_第3张图片

 

这里在补充一个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();

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

opencv 透视变换作用在图上和点上的实现_第4张图片

你可能感兴趣的:(机器学习,深度学习,编程)