C++ Opencv之3D透视变换
前言:
各位小伙伴们是不是经常出现拍摄角度不佳,看着特别难受,想把图片中的某个物体翻转一下呢?
本文就以下面这本书为例,只需要鼠标按照顺时针点击书的四个脚就可以完成变换:
效果:
目录
流程讲解:
1.先读取一个需要3D透视变换的图片,并创建一个MAT类型的图片变量,用来装处理后的图片
2.创建一个向量,用来存放鼠标点击的四个坐标点在处理后的图片变量中的位置
3.由于涉及到鼠标左键点击,需要创建一个结构体
4.创建一个刚才定义的结构体,并将读取到的原图片的图片变量保存给结构体,并调用鼠标点击函数
5.把点击的位置丢给计算函数,让其使用RANSAC算法,得出计算结果
6.结果转换,并将结果显示
7.如何使用:
所有的代码:
流程讲解:
1.先读取一个需要3D透视变换的图片,并创建一个MAT类型的图片变量,用来装处理后的图片
Mat image=imread("D:/Qt_Opencv_Project/book1.png");Mat result=Mat::zeros(400,500,CV_8UC1);//400*500的大小,但是里面没有东西
2.创建一个向量,用来存放鼠标点击的四个坐标点在处理后的图片变量中的位置
听着可能有点乱,但是没事,往下看就懂了,顺便show一下原图片,方便后续的鼠标操作
vector <Point2f>obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(500,0));obj.push_back(Point2f(500,400));obj.push_back(Point2f(0,400));//转换后的坐标imshow("image",image);
3.由于涉及到鼠标左键点击,需要创建一个结构体
结构体中需要有一个放原图片(方便点击产生的小点能直接显示在图片上,看起来比较直观),另一个存放鼠标点击的坐标点
struct imagedata
{Mat img;vector <Point2f> points;
};
4.创建一个刚才定义的结构体,并将读取到的原图片的图片变量保存给结构体,并调用鼠标点击函数
注意这个鼠标处理函数的参数为:
窗口名 鼠标处理的回调函数 处理结果产生数据保存给哪个变量
struct imagedata data;data.img=image;setMouseCallback("image",mouseHundle,&data);//鼠标处理的回调函数waitKey(0);//按任意键关闭当前显示的窗口,显示下一个窗口
调用的回调函数:
第一个参数为鼠标点击的命令
第二、三个参数为点击的坐标
第四个参数为标记(保留,本次没有使用到)
第五个参数为传入的数据,将处理好的图片信息保存到这里,根据上面的代码,我们所传入的是一个第三点中自己创建的结构体
此回调函数的内容:
判断点击的是否为鼠标左键,如果是,则在点击位置画一个小红点,如果已经保存的小红点数目小于4个则保存小红点(为什么是4个?因为本文以书本为例,以书本的四个角来确定一本书在图片中的位置)
void mouseHundle(int event,int x,int y,int flag,void *per)
{struct imagedata * d=(struct imagedata*)per;//强转一下方便后面操作if(event==EVENT_LBUTTONDOWN){//确定按下的是鼠标左键//用圆形标记一下鼠标按下左键标记的位置circle(d->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);//在图上标记,圆心为点击的位置imshow("image",d->img);//原窗口上显示if(d->points.size()<4){d->points.push_back(Point2f(x,y));//把点击的点存起来}}
}
5.把点击的位置丢给计算函数,让其使用RANSAC算法,得出计算结果
作用:将四个鼠标点击的坐标及其框的内容,转换成刚才第二点中保存的结果图片的坐标
函数参数: 四个鼠标点击的坐标 需要转换的四个坐标 RANSAC算法的宏定义
返回值:图片变量(可以理解成保存刚才那张图片处理的格式,在下一点中可以将原图以这个规则转换成结果图)
Mat res=findHomography(data.points,obj,CV_RANSAC); //利用RANSAC算法计算出来一个小矩阵
6.结果转换,并将结果显示
将原图按照上一点中得到的计算结果,进行转换
参数: 原图 装效果图的图片变量 图片计算结果 装效果图的图片变量的大小
warpPerspective(image,result,res,result.size()); //结果转换imshow("result",result);waitKey(0);
7.如何使用:
导入图片以后,按照顺时针点击你想要3D变换的目标(比如本例是那本书)的四个角,然后按下任意键(别是关机键。。)结果就会跳出来啦!
所有的代码:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;struct imagedata
{Mat img;vector <Point2f> points;
};void mouseHundle(int event,int x,int y,int flag,void *per)
{struct imagedata * d=(struct imagedata*)per;if(event==EVENT_LBUTTONDOWN){//确定按下的是鼠标左键//用圆形标记一下鼠标按下左键标记的位置circle(d->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);//在图上标记,圆心为点击的位置imshow("image",d->img);//原窗口上显示if(d->points.size()<4){d->points.push_back(Point2f(x,y));//把点击的点存起来}}
}void example_1()
{Mat image=imread("D:/Qt_Opencv_Project/book1.png");Mat result=Mat::zeros(400,500,CV_8UC1);//400*500的大小,但是里面没有东西//存放四个转换以后的坐标vector <Point2f>obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(500,0));obj.push_back(Point2f(500,400));obj.push_back(Point2f(0,400));//转换后的坐标imshow("image",image);struct imagedata data;data.img=image;setMouseCallback("image",mouseHundle,&data);//鼠标处理的回调函数waitKey(0);//按任意键关闭当前显示的窗口,显示下一个窗口Mat res=findHomography(data.points,obj,CV_RANSAC); //利用RANSAC算法计算出来一个小矩阵warpPerspective(image,result,res,result.size()); //结果转换imshow("result",result);waitKey(0);
}int main(int argc, char *argv[])
{example_1();return 0;
}
看完别忘三连哦!您的支持是对我最大的鼓励!
博主往期的其他实用文章:
C++使用opencv调用级联分类器来识别目标物体_一个不同的ID的博客-CSDN博客前言:相较于帧差法捕捉目标物体识别,级联分类器识别目标物体更加具有针对性,使用前者只要是动的物体都会被捕捉识别到,画面里有一点风吹草动,都会被捕捉识别下来,如果我想识别具体的人或者物,都无法做到精准的目标识别,所以有了级联分类器识别(即模型识别),会按照训练好的级联分类器(模型)来进行目标识别流程讲解:1.创建一个级联分类器对象创建一个级联分类器对象,并读取已经已经训练好的模型 CascadeClassifier cascade;//级联分类器(模型) cascadehttps://blog.csdn.net/baidu_38326512/article/details/124271434?spm=1001.2014.3001.5502C++调用opencv完成运动目标捕捉_一个不同的ID的博客-CSDN博客一、原理说明:差帧识别原理:将这一帧的图像和上一帧的图像进行比对,产生变化的即为运动的目标像素块二、过程详解:1.将传入的两帧先进行灰度处理,转化将rgb类型图片转化为灰度图,可大大降低处理时间和资源消耗将转换后的图片转存至frontGray和afterGray cvtColor(frontFrame,frontGray,CV_BGR2GRAY); cvtColor(afterFrame,afterGray,CV_BGR2GRAY);2.将两帧图片进行...https://blog.csdn.net/baidu_38326512/article/details/124236389?spm=1001.2014.3001.5502
C++ Opencv之3D透视变换相关推荐
- OpenCV创建3D直方图
OpenCV创建3D直方图 创建3D直方图 目标 代码 解释 结果 创建3D直方图 目标 在本教程中,您将学习如何 为可视窗口创建自己的回调键盘功能. 在可视窗口中显示3D直方图. 代码 #inclu ...
- opencv 仿射变换与透视变换详解
常见的2D图像变换从原理上讲主要包括基于2×3矩阵的仿射变换和基于3×3矩阵透视变换. 仿射变换 原理 基本的图像变换就是二维坐标的变换:从一种二维坐标(x,y)到另一种二维坐标(u,v)的线性变换: ...
- Opencv中3D显示模块viz安装
Opencv中3D显示模块viz安装 文章目录 前言 安装cmake 编译viz 编译opencv 3.4.4 4.0.0 VS2015测试 前言 最近工作需要在VS2105中调用opencv的 ...
- opencv生成3d模型_OpenCV4.2使用viz模块显示3D图像
在OpenCV 3D视觉中如果需要显示三维数据或图像就需要用到viz模块,viz是OpenCV的3D显示模块,OpenCV官方release版本不包含此模块,需要我们自己cmake编译. Cmake步 ...
- 知微传感Dkam系列3D相机OpenCV应用篇:OpenCV读入3D相机数据
OpenCV读入3D相机数据 写在前面 本人从事机器视觉细分的3D相机行业.编写此系列文章主要目的有: 1.便利他人应用3D相机,本系列文章包含公司所出售相机的SDK的使用例程及详细注释: 2.促进行 ...
- OpenCV中的透视变换介绍
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 透视变换原理 透视变换是将图像从一个视 ...
- OpenCV Viz 3D虚拟空间模块
在OpenCV2.4.9发布release版本时添加了3D模块,实现起来非常简洁漂亮,三维虚拟空间模块是集成自三维计算机图形学.图像处理和可视化的VTK得到的,OpenCV3.0的OpenCV tut ...
- 基于OpenCV的图像透视变换详解(从理论到实现再到实践)
一.仿射变换与透视变换 一直无法理解两种仿射变换与透视变换的区别,因此详细学习了两种变换的具体细节,重新书写了公式,并给出自己的一些看法. 1.仿射变换 可以认为,仿射变换是透视变换的一种特例. ...
- Opencv学习笔记 透视变换/单应性变换
1.透视变换概述 透视变换(Perspective Transformation),又称Homography Transformation. 在计算机视觉领域,空间中同一平面的任意两幅图像通过单应性关 ...
最新文章
- 多线程(C++)临界区Critical Sections
- jstree 节点拖拽保存数据库
- 工作103:组装查询
- android在线root,KingRoot全球率先实现Android 7.0一键 Root
- 【干货】一张蓝图九大行动领域,实现AI赋能的企业转型-IBM.pdf(附下载链接)...
- 金三银四Java面试的一些感受,实战篇
- 手动写一个上传图片的组件,不适用插件,包括限制图片大小,格式
- 数据库系统:NoSQL与SQL的区别
- C++中使用GSoap
- turbo c是什么?
- Maven中的dependencyManagement 详解
- 甜在心馒头店通过泊松分布解决备货烦恼
- 太阳辐射最少的地区_我国太阳辐射总量最少的是哪一个地区?
- 【容器化部署简介】 基于腾讯云TKE: kubernetes(k8s), github actions, devops
- 手机布局rem的使用(rem)
- 消失的2000万辆小黄车去哪儿了?
- Qwt使用之QwtPlot
- powerbuilder 9.0+下载 (内含补丁 build 7096)
- E-office OA 任意文件下载漏洞复现
- oracle数据库extract,Oracle中extract()函数
热门文章
- 人工神经网络技术及应用,人工神经网络发展前景
- 附近商家位置java开发附近定位
- 快速进化 | 新一代科学计算软件 MWORKS.Syslab 2022b 更新发布
- 2017年6月历史文章汇总
- DeepRMethylSite:一种基于深度学习的蛋白质精氨酸甲基化位点预测方法
- 华夏文明的传统气功到底是有一定科学性还是彻底的伪科学(ZZ)
- 创业两年,一家小VC的自我反思
- 大疆文档(8)-Android教程-模拟器App
- CVPR 2021 论文解读I 动态区域感知卷积,进一步提升分类/检测/分割性能|Dynamic Region-Aware Convolution
- Echarts3实例 map地图选中高亮显示