前言:
各位小伙伴们是不是经常出现拍摄角度不佳,看着特别难受,想把图片中的某个物体翻转一下呢?
本文就以下面这本书为例,只需要鼠标按照顺时针点击书的四个脚就可以完成变换:
效果:
目录
流程讲解:
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;
}
看完别忘三连哦!您的支持是对我最大的鼓励!
博主往期的其他实用文章:文章来源:https://www.toymoban.com/news/detail-777591.html
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文章来源地址https://www.toymoban.com/news/detail-777591.html
到了这里,关于C++ Opencv之3D透视变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!