• 【OpenCV】 透视变换 生活实际场景中的应用


    目录

    一:透视变换的实际应用场景

    二:案例了解透视变换--书本视图矫正

    三:案例了解透视变换--广告屏幕切换


    一:透视变换的实际应用场景

    我们在出门坐车时,经常会看到司机会使用一种行车辅助工具,这其中就使用到了透视变换的相关操作,协助司机安全行车。

    可以看出,自身小车周围路况的正常显示,便利了司机的行车操作 

    像这种透视变换的实际生活应用,其实还有许多,接下来,我们就来学习一下OpenCV的透视变换

    二:案例了解透视变换--书本视图矫正

    原图:

    目标:需要使用透视变换 将书桌上的课本 正视视角查看

    结果展示:

    书本视图矫正完整代码如下:【这里是鼠标点击从左上角开始顺时针选取4个点透视变换】

    1. #include
    2. #include
    3. #include
    4. using namespace cv;
    5. using namespace std;
    6. //鼠标操作 自己准备结构体
    7. struct imagedata
    8. {
    9. Mat img;//目标图像 用于点击 确定坐标
    10. vector points;//存放原图的坐标 通过鼠标的点击进行存放
    11. };
    12. //鼠标操作的回调函数:用于选择四个角的点(使用方法:从左上角开始顺时针选择四个点,选完之后回车操作)
    13. void mouseHundle(int event,int x,int y,int flag,void *arg)
    14. {
    15. //强制转换
    16. struct imagedata * d = (struct imagedata*)arg;
    17. //如果按下的是鼠标左键
    18. if(event==EVENT_LBUTTONDOWN)
    19. {
    20. //用圆形来标记下鼠标按下左键标记的位置
    21. circle(d->img,Point(x,y),3,Scalar(255,0,0),3,CV_AA);//在图上标记,圆心为点击的位置
    22. imshow("image",d->img);//原窗口上进行显示标记点
    23. //透视变换 需要使用四个点的坐标
    24. if(d->points.size()<4)
    25. {
    26. d->points.push_back(Point2f(x,y));//把点击下来的坐标进行存储
    27. }
    28. }
    29. }
    30. void example_1()
    31. {
    32. Mat image=imread("D:/00000000000003jieduanshipincailliao/book2.jpg");
    33. Mat result=Mat::zeros(400,500,CV_8UC1);//最终结果显示 单通道
    34. //准备坐标:存放四个转换以后的坐标
    35. vectorobj;
    36. //坐标一定要相反 镜像坐标
    37. obj.push_back(Point2f(0,0));
    38. obj.push_back(Point2f(500,0));
    39. obj.push_back(Point2f(500,400));
    40. obj.push_back(Point2f(0,400));
    41. imshow("image",image);
    42. struct imagedata data;
    43. data.img=image;
    44. //鼠标操作 鼠标处理的回调函数
    45. setMouseCallback("image",mouseHundle,&data);
    46. //按任意键关闭当前显示的窗口,显示下一个窗口
    47. waitKey(0);
    48. //利用RANSAC算法 计算得到转换映射矩阵3*3
    49. Mat res=findHomography(data.points,obj,CV_RANSAC);
    50. //查看转换矩阵
    51. //imshow("res",res);
    52. //原图转换出来结果图
    53. warpPerspective(image,result,res,result.size());
    54. //查看转换结果图 透视变换
    55. imshow("result",result);
    56. waitKey(0);
    57. }
    58. int main(int argc, char *argv[])
    59. {
    60. example_1();
    61. return 0;
    62. }

    以上是使用鼠标点击确定坐标,当然,我们也可以在代码中写上选定的坐标进行透视变换的相关操作。 依然选取左上角开始顺时针坐标选取,这里以左上角为例,其他三个点可以类比左上角坐标选择来确定下坐标选取

    可以看到左上角坐标 x=282,y=43

    自己定下透视变换使用到的四个坐标 直接回车 即可查看透视变换结果

    1. //鼠标操作 鼠标处理的回调函数
    2. //setMouseCallback("image",mouseHundle,&data);
    3. //不使用鼠标点击,自己定下透视变换的四个坐标
    4. vectorsrc;
    5. src.push_back(Point2f(283,134));
    6. src.push_back(Point2f(745,234));
    7. src.push_back(Point2f(578,463));
    8. src.push_back(Point2f(61,299));
    9. //按任意键关闭当前显示的窗口,显示下一个窗口
    10. waitKey(0);
    11. //利用RANSAC算法 计算得到转换映射矩阵3*3
    12. Mat res=findHomography(src,obj,CV_RANSAC);
    13. //查看转换矩阵
    14. //imshow("res",res);

    程序运行 直接回车操作 查看

    三:案例了解透视变换--广告屏幕切换

    背景图片: 

    想要切换的广告图片: 

    目标:选择广告屏幕 切换 广告屏幕内容

    结果:广告屏上面的 内容推荐 成功切换成自己想要切换的广告图片

    实现方法:处理后两张图片的叠加,就是先将想要更换的广告屏填充黑色背景图,再将自己想要的广告图片 两张图片叠加就能达到切换广告屏幕的效果

    广告屏幕切换完整代码如下:

    1. #include
    2. #include
    3. using namespace cv;
    4. using namespace std;
    5. struct imagedata
    6. {
    7. Mat img;//目标图像
    8. vector points;//3D点
    9. };
    10. //鼠标操作函数:用于选择四个角的点(使用方法有顺序的,从左上角顺时针选择,选完之后回车)
    11. void mouseHundle(int event,int x,int y,int flag,void *ptr)
    12. {
    13. struct imagedata * d=(struct imagedata*)ptr;
    14. if(event==EVENT_LBUTTONDOWN)
    15. {
    16. //确定按下的是鼠标左键
    17. //用圆形标记一下鼠标按下左键标记的位置
    18. circle(d->img,Point(x,y),3,Scalar(255,0,0),3,CV_AA);//在图上标记,圆心为点击的位置
    19. imshow("dst",d->img);//在dst背景图中显示鼠标选取的图片
    20. if(d->points.size()<4)//只存下来,最先点的前四个点
    21. {
    22. d->points.push_back(Point2f(x,y));//把鼠标操作点击的点存起来
    23. }
    24. }
    25. }
    26. void example_2()
    27. {
    28. Mat image1=imread("D:/00000000000003jieduanshipincailliao/0802.jpg");//想要切换的广告内容
    29. Mat image2=imread("D:/00000000000003jieduanshipincailliao/city.jpg");//纽约时代广场图片背景
    30. Mat dst=image2.clone();//背景图片 克隆
    31. //存放原图坐标 想要切换的广告屏图片
    32. vector obj;
    33. obj.push_back(Point2f(0,0));
    34. obj.push_back(Point2f(image1.cols,0));
    35. obj.push_back(Point2f(image1.cols,image1.rows));
    36. obj.push_back(Point2f(0,image1.rows));
    37. //纽约时代广场图背景图显示
    38. imshow("dst",dst);
    39. struct imagedata data;
    40. data.img =dst;
    41. //鼠标操作 鼠标处理的回调函数
    42. setMouseCallback("dst",mouseHundle,&data);
    43. //按任意键关闭当前显示的窗口,显示下一个窗口
    44. waitKey(0);
    45. //计算得到转换映射矩阵 3*3 原图坐标转换为鼠标选择
    46. Mat res = findHomography(obj,data.points,CV_RANSAC);
    47. //imshow("res",res);
    48. //透视变换
    49. warpPerspective(image1,dst,res,dst.size());
    50. //仅有的却换后的广告图图片
    51. //imshow("image1",dst);
    52. Point pts[4];
    53. for(int i=0;i<4;i++)
    54. {
    55. pts[i]=data.points[i];
    56. }
    57. //鼠标点选的四个坐标的区域填充成黑色
    58. fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);
    59. //imshow("image2",image2);
    60. //将仅有的却换后的广告图图片 和 鼠标点选的四个坐标的区域填充成黑色的背景图图片 叠加
    61. image2+=dst;
    62. //显示出最后广告换屏结果图片
    63. imshow("final",image2);
    64. waitKey(0);
    65. }
    66. int main(int argc, char *argv[])
    67. {
    68. example_2();
    69. return 0;
    70. }
  • 相关阅读:
    【C++】搜索二叉树底层实现
    长安汽车董事长下场宣传原力技术 全擎引领电动化出行普及时代
    为什么要使用零知识证明来开发跨链协议
    static assertion failed: Error: no SVD traits
    射频识别|计算机网络|第九讲数据通信和编码技术|奈氏准则和香农定理
    可视化开源自定义表单的特点表现在哪里?
    API接口接入电商平台案例,采集淘宝天猫拼多多1688京东LAZADA数据按关键字搜索商品示例
    PHP 定时任务获取微信 access_token
    python poetry的教程
    清易低功耗智能雨量监测站概述
  • 原文地址:https://blog.csdn.net/m0_56051805/article/details/126127415