透视变换原理我也不细说,原理可以参考:https://blog.csdn.net/xiaowei_cqu/article/details/26471527

在opencv中只要调两个函数就可以了。
cv::Mat warpMatrix = cv::getPerspectiveTransform(src_pt, dst_pt);
cv::warpPerspective(SrcImg, m_src_correct, warpMatrix, SrcImg.size(), cv::INTER_NEAREST, cv::BORDER_CONSTANT);
src_pt是原来物体的4个点坐标,dst_pt是根据原来的坐标计算得来的,一般是原来坐标的外接矩形。

#include <iostream>
#include <opencv2/opencv.hpp>
bool correct_cjh_3(cv::Point2f pt_tl,cv::Point2f pt_bl,cv::Point2f pt_tr,cv::Point2f pt_br,cv::Mat &SrcImg,cv::Mat &m_MingP,bool b_debug)
{//   0   2//   1   3Mat m_src_correct;cv::Point2f src_pt[4];cv::Point2f dst_pt[4];src_pt[0] = pt_tl;src_pt[1] = pt_bl;src_pt[2] = pt_tr;src_pt[3] = pt_br;int T_1 = 0;int T_2 = 0;dst_pt[0] = cv::Point(MIN(src_pt[0].x,src_pt[1].x) - T_1,MIN(src_pt[0].y,src_pt[2].y));dst_pt[1] = cv::Point(MIN(src_pt[0].x,src_pt[1].x) -T_1,MAX(src_pt[1].y,src_pt[3].y));dst_pt[2] = cv::Point(MAX(src_pt[2].x,src_pt[3].x) + T_2,MIN(src_pt[0].y,src_pt[2].y));dst_pt[3] = cv::Point(MAX(src_pt[2].x,src_pt[3].x) + T_2,MAX(src_pt[1].y,src_pt[3].y));Point ptout_tl(dst_pt[0].x,dst_pt[0].y);Point ptout_br(dst_pt[3].x,dst_pt[3].y);Rect roi_mingp = Rect(ptout_tl,ptout_br);cv::Mat warpMatrix = cv::getPerspectiveTransform(src_pt, dst_pt);cout<<"warpMatrix=\n"<<warpMatrix<<endl;cv::warpPerspective(SrcImg, m_src_correct, warpMatrix, SrcImg.size(), cv::INTER_NEAREST, cv::BORDER_CONSTANT);RoiCorrect(m_src_correct,roi_mingp);m_MingP = m_src_correct(roi_mingp).clone();Point pt_center = Point(SrcImg.cols/2,SrcImg.rows/2);if(b_debug){Mat m_show = m_src_correct.clone();rectangle(m_show,roi_mingp,cv::Scalar(0,255,255),1);Mat SrcImg_cp = SrcImg.clone();circle(SrcImg_cp,pt_center,9,Scalar(255,0,0),3);cv::namedWindow("SrcImg",cv::WINDOW_NORMAL);cv::imshow("SrcImg",SrcImg_cp);cv::Mat_<double> mat_pt(3,1);mat_pt(0,0) = pt_center.x;mat_pt(0,1) = pt_center.y;mat_pt(0,2) = 1;cout<<"mat_pt==\n"<<mat_pt<<endl;Point pt_correct;Mat mat_tmp = warpMatrix * mat_pt;std::cout<<"mat_tmp=\n"<<mat_tmp<<std::endl;double a1 = mat_tmp.at<double>(0,0);double a2 = mat_tmp.at<double>(1,0);double a3 = mat_tmp.at<double>(2,0);cout<<"a1="<<a1<<"   a2="<<a2<<"   a3="<<a3<<endl;pt_correct = Point(a1,a2);circle(m_show,pt_correct,10,cv::Scalar(0,255,255),8);cv::namedWindow("correctPic",cv::WINDOW_NORMAL);cv::imshow("correctPic",m_show);cv::namedWindow("correctRoi",cv::WINDOW_NORMAL);cv::imshow("correctRoi",m_MingP);waitKey(0);}return true;
}int main() {Mat img = imread("/data_2/everyday/0317/bugall_snapshot22.png");cv::Point2f pt_tl = Point2f(367,0);cv::Point2f pt_tr = Point2f(605,58);cv::Point2f pt_bl = Point2f(11,162);cv::Point2f pt_br = Point2f(281,351);Mat m_roi;bool b_debug = true;correct_cjh_3(pt_tl,pt_bl,pt_tr, pt_br,img,m_roi,b_debug);
}

一般情况下我们用透视变换到这里就可以了,拿到透视变换后的图继续处理就可以,但是在某些情况下需要点的映射。比如原图的中心点经过透视变换之后该点在哪里?按照下面的矩阵相乘,按理说,点坐标乘以透视变换矩阵就可以了。

但是,实践起来并不是这样的,透视变换矩阵是33的,点坐标是(x,y),为了相乘,点坐标需要补上1,(x,y,1)。因为透视变换是三维里面的变换,需要z坐标。代码中可以看到我把各个矩阵都打印出来了:
warpMatrix=
[2.175396430644075, 4.822550437851066, -786.7332303651573;
-0.5767283475053204, 2.366574943211475, 211.6593035344521;
0.0001578547637398106, 0.004169585228612301, 1]
mat_pt==
[316;
186;
1]
mat_tmp=
[797.6864231586686;
469.5960851601052;
1.825424957863668]
a1=797.686 a2=469.596 a3=1.82542
在变换之后的图上并没有找到我画的变换之后的中心点。应该是超出图像范围了。。。经过一顿乱操作,左乘右乘还是不行。再仔细看看图片,透视变换之后好像被裁剪了一点,感觉是因为裁剪导致坐标对不上了的。。。。后来同事帮忙,弄对了。说需要归一化,让我把得到的点第三个坐标变为1,这样归一化同一个平面。
pt_correct = Point(a1
1.0/a3,a2*1.0/a3);

哈哈,果真出来了!!!
还有个问题,就是已知透视变换之后的图上点,如何知道该点变换之前的坐标?

透视变换--点对应变换相关推荐

  1. ps进行透视变换(扭曲变换)

    在深度学习中,很多网络在画图时,对图像进行透视变换,将图像"立起来". 如下面的Oriented Response Networks: 打开–图像–设置画布大小–用魔棒选择,然后删 ...

  2. 图像处理二:仿射变换和透视变换

    一.仿射变换(Affine Transformation) 放射变换(平面变换.二维坐标变换):是空间直角坐标系的变换,从一个二维坐标变换到另一个二维坐标,仿射变换是一个线性变换,保持了图像的&quo ...

  3. 基于边缘检测和透视变换的文档图像校正

    实验任务与要求: 对发生透视变换的文档图像进行几何校正处理,得到规范的文档图像. 几何校正的目的是把发生了透视变换的目标变换为具有真实比例和角度的目标,如下图所示:左图中的地板砖经过透视变换之后,不再 ...

  4. 透视变换原理实例代码详解

    导读 在上篇文章中,我们介绍了仿射变换,我们只需要通过一个两行三列的变换矩阵M就能够对图像实现平移.缩放.翻转.旋转操作.我们发现这些变换其实都属于平面变换,如果我们想要进行空间变换呢? 将上图的扑克 ...

  5. 关于图像变换的总结(仿射变换,刚体变换等)

    一.常用的图像变换模型 :刚性变换.仿射变换.透视变换和非线形变换等.如下图所示: 进一步理解 (1) 刚体变换  如果一幅图像中的两点间的距离经变换到另一幅图像中后仍然保持不变,则这种变换称为刚体变 ...

  6. 几种图像变换 刚体变换 仿射变换 投影变换

    转自:https://www.cnblogs.com/bnuvincent/p/6691189.html http://www.cnblogs.com/ghj1976/p/5199086.html 变 ...

  7. 章节二 几何基元与变换

    几何基元和变换 用以描述三维形状的基本构件. 2D点:用一对数值表示(x,y),也可以使用其次坐标来表示,齐次矢量可以通过可以除以最后一个元素转换为非齐次矢量.(其次坐标:在进行几何变换时,为了加快运 ...

  8. 飞越星空屏保实现:3D数学之透视变换

    最近想实践总结下3D图形学的一些内容 所以,就做出了这个东西. 本来打算用C++写的, 但考虑到MFC的丑陋和C++使用GDI/GDI+的各种不方便 遂用C#实现之,以简化实现手段. 呵呵,C#是做某 ...

  9. 【CV】OpenCV(基于Python)学习笔记

    以下内容中的页码均来自<OpenCV 4详解 : 基于Python> 目录 第2章 载入.显示与保存数据 2.2 图像的读取与显示 2.2.1 图像读取函数 cv.imread() 2.2 ...

最新文章

  1. jquery下拉菜单
  2. cp -r dir1/. dir2 表示将dir1下的文件复制到dir2,不包括dir1目录
  3. ERROR MESSAGE: Invalid command line: Malformed walker argument: Could not find walker with name
  4. The way of Webpack learning (II.) -- Extract common code(多页面提取公共代码)
  5. dz论坛ucenter打不开mysql_Discuz论坛搬家 ucenter info:can not connect to MySQL server解决办法...
  6. VTK修炼之道58:图形基本操作进阶_点云配准技术(迭代最近点ICP算法)
  7. wps分享为什么要登入_[win]为什么你需要便携应用?portableapps让你得心应手.
  8. c语言自动取款机贴吧,求助 简单atm机的循环操作
  9. Mac OS开发—Xcode给Mac应用添加编辑快捷键(剪切 复制 粘贴 全选 删除 撤销 重做)功能
  10. 两路语音 两路计算机数据综合,两路语音PCM时分复用系统的设计.DOC
  11. 计算机组成原理—地址码
  12. java scjp 试题_JAVA认证:78道SCJP考试试题精解
  13. YUY2和MJPG视频编码格式区别
  14. 台式计算机如何取消屏幕密码,台式电脑怎么取消锁屏?
  15. css3 3d 太阳系,css3太阳系9大行星介绍页面动画
  16. E哥的Git教程(一)
  17. matlab 半导体激光模拟工具箱,MATLAB中的激光器仿真
  18. ISP--Black Level Correction(黑电平矫正)
  19. 澳洲移民监 盘点一下各国的移民监要求
  20. Windows下截图快捷键

热门文章

  1. DDoS攻击--Syn_Flood攻击防护详解(TCP)
  2. 推荐这款,SpringBoot 开源商城系统,挣钱太轻松了
  3. form.submit() 提交部分浏览器不管用
  4. 华中师范大学微型计算机技术,许静芳(华中师范大学计算机学院副教授)_百度百科...
  5. STM32使用SWD下载
  6. 计算机考研规划 知乎,考研知乎最全117个问题!看完让你的考研成功率大大提高...
  7. Hang Detect 问题分析案例
  8. 2020年最新 C# .net 面试题,月薪20K+中高级/架构师必看(五)
  9. 悟空分词与mysql结合_中文分词与关键词提取实践小结
  10. java计算机毕业设计合同管理MyBatis+系统+LW文档+源码+调试部署