OpenCV-透视变换及对二维点求透视变换之后的坐标

微信公众号:幼儿园的学霸
个人的学习笔记,关于OpenCV,关于机器学习, …。问题或建议,请公众号留言;

目录

前言

基本原理

OpenCV透视变换函数代码

前言

  在做车道线检测中用到了透视变换的一点内容,用于将相机拍摄的图像转换到道路平行的视角下,即鸟瞰图,然后在鸟瞰图中进行车道线检测。
  如图1、图2所示分别为相机拍摄的原始图像和逆透视变换后的图像,一般来说逆透视变换后的两条车道线应该是平行的,此处不平行应是透视变换矩阵没有选好,在实际项目中发现没有影响,毕竟图2中过滤掉了大部分杂乱线段。此处对逆透视变换内容进行记录,方便日后查找。

图1 原始图像

图2 鸟瞰图

基本原理

  透视变换(Perspective Transformation)是将成像投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。如图3,通过透视变换ABC变换到A'B'C'。

图3 透视变换示意

  透视变换通用公式为:

其中为源图像的像素坐标,为源图像变换后的点所对应的像素坐标。透视变换矩阵可以拆程如下4个部分:

,表示图像的线性变换,比如scaling,shearing和ratotion,产生透视变换,用于平移。
  根据透视变换的通用公式,可以得到透视变换的数学表达式为:


从上面的计算公式可以看到,透视变换部分是其分母,而线性变换和平移部分是作为分子存在的。
  因此,给定透视变换对应的四对点坐标,可以求得透视变换矩阵;反之,给定透视变换矩阵,也可以对图像或者坐标点完成透视变换。

OpenCV透视变换函数

在我所写车道线检测代码中,透视变换部分用到了以下3个函数

//用于求得透视变换的变换矩阵,
//src::源图像上的四个顶点坐标
//dst::src的坐标在目标图像上的对应坐标
//返回值:3X3的透视变换矩阵
//在车道线检测代码中作用:得到将原始图转换到鸟瞰图的转换矩阵
cv::Mat getPerspectiveTransform(const Point2f* src, const Point2f* dst)
//求得点/点数组在经过变换矩阵m后的对应坐标
//src:目标点,如鸟瞰图中的坐标
//m:src到dst的转换矩阵
//dst:src经过m转换后的对应点
在车道线检测代码中作用:将鸟瞰图中的车道线坐标转换到原始视图下的像素作弊码
void perspectiveTransform(InputArray src, OutputArray dst, InputArray m ) //对图像进行透视变换
//src:输入图像
//dst:输出图像
//M:变换矩阵,如getPerspectiveTransform函数得到的矩阵
//dsize:目标图像的大小
//flags:目标图像的插值方法
//borderMode:外推方法
//borderValue:常量边界时使用
//在车道线检测代码中作用:
//   1.将原始图像转换到鸟瞰图中,进行车道线检测;
//   2.将鸟瞰图转换到原始视图下,以进行结果展示等
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

代码

代码示例如下。该代码流程为:
1.通过4对点计算透视变换矩阵T;
2.利用T对图像进行逆透视变换得到鸟瞰图;
3.将鸟瞰图下的车道线坐标转换到正常视图下;
该流程和我项目中的流程一致,但展示的代码比较简单,仅做示例。
如图4所示为鸟瞰图下的车道线,图5位转换到原始视图视角下的车道线。

图4 鸟瞰图及其车道线

图5 原始视图及其车道线

具体代码:

//====================================================================//
// Created by liheng on 19-2-12.
//Program:将逆透视变换后的坐标点转换到原图中
//Data:2019.2.12
//Author:liheng
//Version:V1.0
//====================================================================//#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>int main()
{//首先读入图像cv::Mat srcImage = cv::imread("../pictures/000177.png",cv::IMREAD_GRAYSCALE);//定义源点和目标点,源点为正常读入的图像的点,目标点为转换后的鸟瞰图上的对应点cv::Point2f srcPoints[4],dstPoints[4];srcPoints[0] = cv::Point2f(369,375);srcPoints[1] = cv::Point2f(545,221);srcPoints[2] = cv::Point2f(650,221);srcPoints[3] = cv::Point2f(793,375);dstPoints[0] = cv::Point2f(339,375);dstPoints[1] = cv::Point2f(339,211);dstPoints[2] = cv::Point2f(823,211);dstPoints[3] = cv::Point2f(823,375);//1°求解变换矩阵cv::Mat m_persctiveMat = cv::getPerspectiveTransform(srcPoints,dstPoints);//读入图像转换为鸟瞰图的矩阵cv::Mat m_unPersctiveMat =cv::getPerspectiveTransform(dstPoints,srcPoints);//鸟瞰图到原始图像的转换矩阵//2°求解鸟瞰图cv::Mat birdViewImage;cv::warpPerspective(srcImage,birdViewImage,m_persctiveMat,cv::Size(srcImage.cols,srcImage.rows),cv::INTER_LINEAR);//鸟瞰图车道线上的两点.Note:此处为了简单,仅选择2点进行变换std::vector<cv::Point2f> leftLine,rightLine;leftLine.push_back(cv::Point2f(661,0));leftLine.push_back(cv::Point2f(366,376));rightLine.push_back(cv::Point2f(1097,0));rightLine.push_back(cv::Point2f(883,376));//3°求解其在原始图像上对应的坐标std::vector<cv::Point2f> unWarpedLeftLine,unWarpedRightLine;cv::perspectiveTransform(leftLine,unWarpedLeftLine,m_unPersctiveMat);cv::perspectiveTransform(rightLine,unWarpedRightLine,m_unPersctiveMat);//线段可视化cv::cvtColor(srcImage,srcImage,CV_GRAY2BGR);cv::line(srcImage,unWarpedLeftLine[0],unWarpedLeftLine[1],cv::Scalar(0,255,0),2);cv::line(srcImage,unWarpedRightLine[0],unWarpedRightLine[1],cv::Scalar(0,255,0),2);cv::cvtColor(birdViewImage,birdViewImage,CV_GRAY2BGR);cv::line(birdViewImage,leftLine[0],leftLine[1],cv::Scalar(0,255,0),2);cv::line(birdViewImage,rightLine[0],rightLine[1],cv::Scalar(0,255,0),2);cv::imshow("srcImage",srcImage);cv::imshow("birdViewImage",birdViewImage);cv::waitKey(0);return 0;
}

下面的是我的公众号二维码图片,欢迎关注。

图注:幼儿园的学霸

OpenCV-透视变换及对二维点求透视变换之后的坐标相关推荐

  1. python做直方图-python OpenCV学习笔记实现二维直方图

    本文介绍了python OpenCV学习笔记实现二维直方图,分享给大家,具体如下: 官方文档 – https://docs.opencv.org/3.4.0/dd/d0d/tutorial_py_2d ...

  2. 【opencv有趣应用】二维码和条形码的检测

    今天学习下使用opencv进行条形码和二维码的检测 import cv2 import numpy as np from pyzbar.pyzbar import decodedef cv_show_ ...

  3. python3 + opencv +pyzbar实时检测二维码 / 定位二维码,并绘制出二维码的框和提取二维码内容

    python3 + opencv +pyzbar实时检测二维码 / 定位二维码,并绘制出二维码的框和提取二维码内容 1 pyzbar二维码检测模块 1.1. pyzbar模块介绍 1.2 pyzbar ...

  4. Java使用opencv调用微信扫描二维码引擎,附带windows和linux需要的动态库文件

    前言 最近公司项目有一个需求,要用二维码传递数据.于是使用了zxing生成和解析二维码,但是zxing扫描二维码原图还可以,一旦扫描用户使用手机拍摄的二维码,识别率急剧下降.尝试了对拍摄的照片进行降噪 ...

  5. 《C#零基础入门之百识百例》(五十二)封装介绍 -- 二维多项式求值

    C#零基础入门 面向对象 -- 封装介绍 -- 二维多项式求值 前言 一,封装概念 二,封装属性 三,实例练习 -- 二维多项式求值 3.1 题目描述 3.2 问题分析 3.3 参考代码 前言 本文属 ...

  6. c语言二维数组对角线输出字符,用C编程一个4*4的矩阵,用二维数组,求对角线元素的和。,c语言如何使二维数组 输出为矩阵的形式...

    导航:网站首页 > 用C编程一个4*4的矩阵,用二维数组,求对角线元素的和.,c语言如何使二维数组 输出为矩阵的形式 用C编程一个4*4的矩阵,用二维数组,求对角线元素的和.,c语言如何使二维数 ...

  7. 树莓派4b + python3 + pyzbar + opencv + 摄像头 扫描识别二维码(寻找最大的二维码)

    前言 最近需要做一个扫码乘车的功能,于是使用树莓派的摄像头扫描二维码来做一个demo . 网上有部分人用的是zbar这个库,但是我安装后,发现并不能在Python3上使用,这就有点不太好了.经过我的多 ...

  8. 二维搜索求函数极值的python程序

    二维搜索,也就是优化两个未知变量,通常将二维搜索转化为一维搜索进行求解. 例题 二维搜索转一维--黄金分割 求函数二维函数A在某区间的最大值 A=( 6 - 2×l + l×cos(θ) ) × l× ...

  9. C语言求二维数组平均数,一道JavaScript的二维数组求平均数的题

    JavaScript中只支持一维数组,但是可以在数组中嵌套数组来创建二维以至于多维的数组.今天下午在看书时候,发现一道感觉比较有意思的题,就是js中如何求二维数组的列之和和行之和,现在就给大家分享下, ...

最新文章

  1. Tensorflow【实战Google深度学习框架】使用 TFLearn 实现逻辑运算符
  2. java根据日期生成表主键_java 利用时间生成主键
  3. 思科超融合:主推HyperFlex,押注HCI
  4. 如何利用CNKI句子检索功能提高研究效率
  5. matlab高斯滤波跟中值滤波区别,matlab图像滤波处理代码讲解 均值滤波 中值滤波 高斯滤波...
  6. 数学系鄙视物理系的经典桥段,全部看懂了算我输!
  7. wepy组件子父传值_【WePY小程序框架实战三】-组件传值
  8. 将海量文件用split切割清单,并逐一处理
  9. Redis 发布订阅
  10. 设计模式笔记十六:解释器模式
  11. 旷视申请赴港IPO:阿里蚂蚁金服持股近30%
  12. 面试—每日一题(7)
  13. 中国体力活动监测器(PAM)市场趋势报告、技术动态创新及市场预测
  14. 超链接a标签的伪类选择器问题,Link标签与visited标签的失效问题(问题介绍与解决方法)。以下全部内容跟可通过鼠标左键选取后,复制到编辑器中直接运行。
  15. Python之路-4
  16. java类的引用使用即String类的toUpperCase的使用
  17. 【2019秋招】OPPO无线通信协议工程师笔试
  18. RK px30 配置ap6212 wifi bt流程记录
  19. Monaco Editor教程(十八):使用api来完成某些键盘操作,格式化,查找,显示右侧菜单等。
  20. 计算机主机电源接线,七个步骤教你主机电源如何接线

热门文章

  1. 休闲平台,何去何从?(1)
  2. Springboot+Vue+Echarts实现51job大数据岗位分析数据大屏
  3. Sybil_attack (女巫攻击)
  4. 关于在WIN10中使用照片查看器的问题
  5. 超人气思维导图XMind新年新版本,这6个新功能你一定要看
  6. 编程之美1:那些关于1的个数的经典面试题
  7. Unity游戏动画 从入门到住院:动画状态机
  8. [LCT刷题][连通性维护] P3950 部落冲突
  9. 佟年计算机大赛,佟年的人设是什么?
  10. 入手评测 天玑1200和骁龙865对比哪个好