当前位置:网站首页>【OpenCV】 书本视图矫正 + 广告屏幕切换 透视变换图像处理
【OpenCV】 书本视图矫正 + 广告屏幕切换 透视变换图像处理
2022-08-03 12:49:00 【我今年十六岁】
目录
一:透视变换的实际应用场景
我们在出门坐车时,经常会看到司机会使用一种行车辅助工具,这其中就使用到了透视变换的相关操作,协助司机安全行车。
可以看出,自身小车周围路况的正常显示,便利了司机的行车操作
像这种透视变换的实际生活应用,其实还有许多,接下来,我们就来学习一下OpenCV的透视变换
二:案例了解透视变换--书本视图矫正
原图:
目标:需要使用透视变换 将书桌上的课本 正视视角查看
结果展示:
书本视图矫正完整代码如下:【这里是鼠标点击从左上角开始顺时针选取4个点透视变换】
#include <iostream>
#include <opencv2/opencv.hpp>
#include<vector>
using namespace cv;
using namespace std;
//鼠标操作 自己准备结构体
struct imagedata
{
Mat img;//目标图像 用于点击 确定坐标
vector<Point2f> points;//存放原图的坐标 通过鼠标的点击进行存放
};
//鼠标操作的回调函数:用于选择四个角的点(使用方法:从左上角开始顺时针选择四个点,选完之后回车操作)
void mouseHundle(int event,int x,int y,int flag,void *arg)
{
//强制转换
struct imagedata * d = (struct imagedata*)arg;
//如果按下的是鼠标左键
if(event==EVENT_LBUTTONDOWN)
{
//用圆形来标记下鼠标按下左键标记的位置
circle(d->img,Point(x,y),3,Scalar(255,0,0),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:/00000000000003jieduanshipincailliao/book2.jpg");
Mat result=Mat::zeros(400,500,CV_8UC1);//最终结果显示 单通道
//准备坐标:存放四个转换以后的坐标
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);
//利用RANSAC算法 计算得到转换映射矩阵3*3
Mat res=findHomography(data.points,obj,CV_RANSAC);
//查看转换矩阵
//imshow("res",res);
//原图转换出来结果图
warpPerspective(image,result,res,result.size());
//查看转换结果图 透视变换
imshow("result",result);
waitKey(0);
}
int main(int argc, char *argv[])
{
example_1();
return 0;
}
以上是使用鼠标点击确定坐标,当然,我们也可以在代码中写上选定的坐标进行透视变换的相关操作。 依然选取左上角开始顺时针坐标选取,这里以左上角为例,其他三个点可以类比左上角坐标选择来确定下坐标选取
可以看到左上角坐标 x=282,y=43
自己定下透视变换使用到的四个坐标 直接回车 即可查看透视变换结果
//鼠标操作 鼠标处理的回调函数
//setMouseCallback("image",mouseHundle,&data);
//不使用鼠标点击,自己定下透视变换的四个坐标
vector<Point2f>src;
src.push_back(Point2f(283,134));
src.push_back(Point2f(745,234));
src.push_back(Point2f(578,463));
src.push_back(Point2f(61,299));
//按任意键关闭当前显示的窗口,显示下一个窗口
waitKey(0);
//利用RANSAC算法 计算得到转换映射矩阵3*3
Mat res=findHomography(src,obj,CV_RANSAC);
//查看转换矩阵
//imshow("res",res);
程序运行 直接回车操作 查看
三:案例了解透视变换--广告屏幕切换
背景图片:
想要切换的广告图片:
目标:选择广告屏幕 切换 广告屏幕内容
结果:广告屏上面的 内容推荐 成功切换成自己想要切换的广告图片
实现方法:处理后两张图片的叠加,就是先将想要更换的广告屏填充黑色背景图,再将自己想要的广告图片 两张图片叠加就能达到切换广告屏幕的效果
广告屏幕切换完整代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
struct imagedata
{
Mat img;//目标图像
vector <Point2f> points;//3D点
};
//鼠标操作函数:用于选择四个角的点(使用方法有顺序的,从左上角顺时针选择,选完之后回车)
void mouseHundle(int event,int x,int y,int flag,void *ptr)
{
struct imagedata * d=(struct imagedata*)ptr;
if(event==EVENT_LBUTTONDOWN)
{
//确定按下的是鼠标左键
//用圆形标记一下鼠标按下左键标记的位置
circle(d->img,Point(x,y),3,Scalar(255,0,0),3,CV_AA);//在图上标记,圆心为点击的位置
imshow("dst",d->img);//在dst背景图中显示鼠标选取的图片
if(d->points.size()<4)//只存下来,最先点的前四个点
{
d->points.push_back(Point2f(x,y));//把鼠标操作点击的点存起来
}
}
}
void example_2()
{
Mat image1=imread("D:/00000000000003jieduanshipincailliao/0802.jpg");//想要切换的广告内容
Mat image2=imread("D:/00000000000003jieduanshipincailliao/city.jpg");//纽约时代广场图片背景
Mat dst=image2.clone();//背景图片 克隆
//存放原图坐标 想要切换的广告屏图片
vector <Point2f>obj;
obj.push_back(Point2f(0,0));
obj.push_back(Point2f(image1.cols,0));
obj.push_back(Point2f(image1.cols,image1.rows));
obj.push_back(Point2f(0,image1.rows));
//纽约时代广场图背景图显示
imshow("dst",dst);
struct imagedata data;
data.img =dst;
//鼠标操作 鼠标处理的回调函数
setMouseCallback("dst",mouseHundle,&data);
//按任意键关闭当前显示的窗口,显示下一个窗口
waitKey(0);
//计算得到转换映射矩阵 3*3 原图坐标转换为鼠标选择
Mat res = findHomography(obj,data.points,CV_RANSAC);
//imshow("res",res);
//透视变换
warpPerspective(image1,dst,res,dst.size());
//仅有的却换后的广告图图片
//imshow("image1",dst);
Point pts[4];
for(int i=0;i<4;i++)
{
pts[i]=data.points[i];
}
//鼠标点选的四个坐标的区域填充成黑色
fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);
//imshow("image2",image2);
//将仅有的却换后的广告图图片 和 鼠标点选的四个坐标的区域填充成黑色的背景图图片 叠加
image2+=dst;
//显示出最后广告换屏结果图片
imshow("final",image2);
waitKey(0);
}
int main(int argc, char *argv[])
{
example_2();
return 0;
}
边栏推荐
猜你喜欢
Image fusion DDcGAN study notes
PolarFormer: Multi-camera 3D Object Detection with Polar Transformers 论文笔记
基于php校园医院门诊管理系统获取(php毕业设计)
为冲销量下探中低端市场,蔚来新品牌产品定价低至10万?
图像融合SDDGAN文章学习
力扣刷题 每日两题(一)
An工具介绍之钢笔工具、铅笔工具与画笔工具
Oracle is installed (system disk) and transferred from the system disk to the data disk
AMS simulation
基于php志愿者服务平台管理系统获取(php毕业设计)
随机推荐
An工具介绍之宽度工具、变形工具与套索工具
Random forest project combat - temperature prediction
Secure Custom Web Application Login
Feature Engineering Study Notes
通过点击CheckBox实现背景变换小案例
业界新标杆!阿里开源自研高并发编程核心笔记(2022最新版)
An动画基础之按钮动画与基础代码相结合
如何让history历史记录前带时间戳
An基本工具介绍之选择线条工具(包教会)
[Verilog] HDLBits Problem Solution - Circuits/Sequential Logic/Latches and Flip-Flops
层次分析法
Jmeter use
In order to counteract the drop in sales and explore the low-end market, Weilai's new brand products are priced as low as 100,000?
Classes and Objects (lower middle)
五、函数的调用过程
博客记录生活
An工具介绍之钢笔工具、铅笔工具与画笔工具
Using the Work Queue Manager (4)
可视化图表设计Cookbook
An introduction to the skeleton tool