当前位置: 首页 > news >正文

图像处理之Homography matrix(单应性矩阵)

图像处理


文章目录

  • 图像处理
  • 前言


前言

单应性矩阵是投影几何中一个术语,本质上它是一个数学概念,但是在OpenCV中却是有几个函数与透视变换相关的函数,都用到了单应性矩阵的概念与知识。跟很多人一样,刚开始学习图像处理对单应性矩阵不是很了解,通过项目实践慢慢知道了一些这方面的知识和自己对它的理解,就跟大家分享一下。

单应性矩阵概念
这里说的单应性矩阵主要是指平面单应性矩阵,在三轴坐标中XYZ,Z=1这个有点类似于三维的齐次坐标。单应性矩阵主要用来解决两个问题,

一是表述真实世界中一个平面与对应它图像的透视变换
二是从通过透视变换实现图像从一种视图变换到另外一种视图
首先看一下在三维空间中任意两个平面

在这里插入图片描述
上图的中零点分别表示两个平面中任意两个点,(a1、a2)与(b1、b2)是这两点对应的两个方向上的线性向量。对于这两个平面直接的关系我们就可以通过这些点从而进一步确立两个平面直接的关系,而两个平面之间的关系用单应性矩阵来描述如下:

在这里插入图片描述
H表示单应性矩阵,p和q表示三维齐次坐标向量,定义了八个自由度。
这种关系被称为平面单应性。这个当中有一些数学知识推导,感兴趣的大家可以自己去看,我们最重要的是明白这个概念怎么来的。其次知道它的应用场景,下面我们就从应用层面和代码层面来说说单应性矩阵的应用。

  • 用来解决拍照时候图像扭曲问题。这个在上一篇文章透视 变换中讲过,但是 当时没有说这个是单应性矩阵的应用。
  • 此外还两个计算机图形学的应用场景分布是纹理渲染与计算平面阴影。
  • 用来实现图像拼接时候解决对齐问题

应用案例
街拍的时候路两边有很多广告牌,如果在视频实时帧中获取到对应的广告牌位置,就可以获取广告牌的四个角坐标,然后通过准备好的内容,将广告牌内容替换,得到想要的虚拟广告牌效果,而这个过程中最重要的一步,可以通过计算单应性矩阵实现内容替换,演示效果如下:

时代广场的街拍
在这里插入图片描述
在这里插入图片描述

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;
//g++ t1.cpp -o t1 `pkg-config --cflags --libs opencv4`
int main(int argc, char** argv) {
    // load images
    Mat src = imread("bk.png");
    if (!src.data) {
        printf("could not load image...\n");
        return -1;
    }

    // show images
    namedWindow("input image", cv::WINDOW_AUTOSIZE);
    imshow("input image", src);
    Mat replaceImg = imread("fk.png");
    imshow("adv content", replaceImg);

    // 定义两个平面上四个角坐标
    vector<Point> src_corners(4);
    vector<Point> dst_corners(4);

    // 原图像平面四点坐标
    src_corners[0] = Point(0, 0);
    src_corners[1] = Point(replaceImg.cols, 0);
    src_corners[2] = Point(0, replaceImg.rows);
    src_corners[3] = Point(replaceImg.cols, replaceImg.rows);

    // 目标平面四个角坐标
    dst_corners[0] = Point(70, 131);
    dst_corners[1] = Point(168,216);
    dst_corners[2] = Point(21, 199);
    dst_corners[3] = Point(148, 267);

    // 计算单应性矩阵与透视变换
    Mat h = findHomography(src_corners, dst_corners);
    Mat output_img;
    warpPerspective(replaceImg, output_img, h, src.size());

    // create mask
    Mat m1 = Mat::zeros(replaceImg.size(), CV_8UC1);
    m1 = Scalar(255);
    Mat mask_output;
    warpPerspective(m1, mask_output, h, src.size());
    imshow("Mask Result", mask_output);

    // use mask
    Mat result1;
    add(output_img, output_img, result1, mask_output);

    Mat result2;
    bitwise_not(mask_output, mask_output);
    add(src, result1, result2, mask_output);

    // put them together
    Mat result;
    add(result1, result2, result);
    imshow("Final Result", result);
    imwrite("result.png", result);

    waitKey(0);
    return 0;
}

在这里插入图片描述

http://www.dtcms.com/a/109091.html

相关文章:

  • 2025年4月3日(模数转换器)
  • 【Centos】centos7内核升级-亲测有效
  • 【动态规划】P8638 [蓝桥杯 2016 省 A] 密码脱落
  • 树莓派 5 换清华源
  • 【C语言】C语言文件操作指南
  • 质检LIMS系统在垃圾处理厂的应用 垃圾处理质检的三重挑战与LIMS破局之道
  • 管理系统如何帮助你节省时间和成本?
  • 移动端六大语言速记:第7部分 - 文件与输入输出(I/O)
  • 【网络流 图论建模 最大权闭合子图】 [六省联考 2017] 寿司餐厅
  • 二十八、城市建成区提取——领域分析法
  • vulnhub-DC-2通关攻略
  • 从零构建大语言模型全栈开发指南:第五部分:行业应用与前沿探索-5.2.1模型偏见与安全对齐(Red Teaming实践)
  • 新能源汽车测试中的信号调理模块:从原理到实战应用
  • python--文件夹的压缩和解压缩(zipfile/pyzipper)
  • Day15——路由
  • 飞浆PaddlePaddle 猫狗数据大战
  • Pyinstaller 打包flask_socketio为exe程序后出现:ValueError: Invalid async_mode specified
  • 学习threejs,使用Texture纹理贴图,测试repeat重复纹理贴图
  • ngx_regex_init
  • C语言基础要素(019):输出ASCII码表
  • 李沐 X 动手学深度学习--第九章 现代循环神经网络
  • webstorm初始化配置项目
  • MySQL学习集--DDL
  • Python 数据科学实战指南:从零开始构建高效分析流程
  • 单片机学习之SPI
  • JVM深入原理(七)(一):运行时数据区
  • 图形界面设计理念
  • 使用 PyTorch 的 `optim.lr_scheduler.CosineAnnealingLR` 学习率调度器
  • 蓝桥云客-修建灌木
  • Ubuntu环境基于Ollama部署DeepSeek+Open-Webui实现本地部署大模型-无脑部署