前言:

各位小伙伴们是不是经常出现拍摄角度不佳,看着特别难受,想把图片中的某个物体翻转一下呢?

本文就以下面这本书为例,只需要鼠标按照顺时针点击书的四个脚就可以完成变换:

侧着看好难受哦,想看正面怎么办?

效果:

舒服了!!!

目录

流程讲解:

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透视变换相关推荐

  1. OpenCV创建3D直方图

    OpenCV创建3D直方图 创建3D直方图 目标 代码 解释 结果 创建3D直方图 目标 在本教程中,您将学习如何 为可视窗口创建自己的回调键盘功能. 在可视窗口中显示3D直方图. 代码 #inclu ...

  2. opencv 仿射变换与透视变换详解

    常见的2D图像变换从原理上讲主要包括基于2×3矩阵的仿射变换和基于3×3矩阵透视变换. 仿射变换 原理 基本的图像变换就是二维坐标的变换:从一种二维坐标(x,y)到另一种二维坐标(u,v)的线性变换: ...

  3. Opencv中3D显示模块viz安装

    Opencv中3D显示模块viz安装 文章目录 前言 安装cmake 编译viz 编译opencv 3.4.4 4.0.0 VS2015测试 前言    最近工作需要在VS2105中调用opencv的 ...

  4. opencv生成3d模型_OpenCV4.2使用viz模块显示3D图像

    在OpenCV 3D视觉中如果需要显示三维数据或图像就需要用到viz模块,viz是OpenCV的3D显示模块,OpenCV官方release版本不包含此模块,需要我们自己cmake编译. Cmake步 ...

  5. 知微传感Dkam系列3D相机OpenCV应用篇:OpenCV读入3D相机数据

    OpenCV读入3D相机数据 写在前面 本人从事机器视觉细分的3D相机行业.编写此系列文章主要目的有: 1.便利他人应用3D相机,本系列文章包含公司所出售相机的SDK的使用例程及详细注释: 2.促进行 ...

  6. OpenCV中的透视变换介绍

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 透视变换原理 透视变换是将图像从一个视 ...

  7. OpenCV Viz 3D虚拟空间模块

    在OpenCV2.4.9发布release版本时添加了3D模块,实现起来非常简洁漂亮,三维虚拟空间模块是集成自三维计算机图形学.图像处理和可视化的VTK得到的,OpenCV3.0的OpenCV tut ...

  8. 基于OpenCV的图像透视变换详解(从理论到实现再到实践)

    一.仿射变换与透视变换 一直无法理解两种仿射变换与透视变换的区别,因此详细学习了两种变换的具体细节,重新书写了公式,并给出自己的一些看法. 1.仿射变换 可以认为,仿射变换是透视变换的一种特例.    ...

  9. Opencv学习笔记 透视变换/单应性变换

    1.透视变换概述 透视变换(Perspective Transformation),又称Homography Transformation. 在计算机视觉领域,空间中同一平面的任意两幅图像通过单应性关 ...

最新文章

  1. 多线程(C++)临界区Critical Sections
  2. jstree 节点拖拽保存数据库
  3. 工作103:组装查询
  4. android在线root,KingRoot全球率先实现Android 7.0一键 Root
  5. 【干货】一张蓝图九大行动领域,实现AI赋能的企业转型-IBM.pdf(附下载链接)...
  6. 金三银四Java面试的一些感受,实战篇
  7. 手动写一个上传图片的组件,不适用插件,包括限制图片大小,格式
  8. 数据库系统:NoSQL与SQL的区别
  9. C++中使用GSoap
  10. turbo c是什么?
  11. Maven中的dependencyManagement 详解
  12. 甜在心馒头店通过泊松分布解决备货烦恼
  13. 太阳辐射最少的地区_我国太阳辐射总量最少的是哪一个地区?
  14. 【容器化部署简介】 基于腾讯云TKE: kubernetes(k8s), github actions, devops
  15. 手机布局rem的使用(rem)
  16. 消失的2000万辆小黄车去哪儿了?
  17. Qwt使用之QwtPlot
  18. powerbuilder 9.0+下载 (内含补丁 build 7096)
  19. E-office OA 任意文件下载漏洞复现
  20. oracle数据库extract,Oracle中extract()函数

热门文章

  1. 人工神经网络技术及应用,人工神经网络发展前景
  2. 附近商家位置java开发附近定位
  3. 快速进化 | 新一代科学计算软件 MWORKS.Syslab 2022b 更新发布
  4. 2017年6月历史文章汇总
  5. DeepRMethylSite:一种基于深度学习的蛋白质精氨酸甲基化位点预测方法
  6. 华夏文明的传统气功到底是有一定科学性还是彻底的伪科学(ZZ)
  7. 创业两年,一家小VC的自我反思
  8. 大疆文档(8)-Android教程-模拟器App
  9. CVPR 2021 论文解读I 动态区域感知卷积,进一步提升分类/检测/分割性能|Dynamic Region-Aware Convolution
  10. Echarts3实例 map地图选中高亮显示