3小时精通opencv(四) 透视变换与图像拼接

news2024/11/15 9:44:39

3小时精通opencv(四) 透视变换与图像拼接

参考视频资源:3h精通Opencv-Python

文章目录

  • 3小时精通opencv(四) 透视变换与图像拼接
    • 透视变换
    • 图像拼接
    • 全部代码


透视变换

透视变换建立两平面场之间的对应关系, 将原始图片投影到一个新的视平面上

# Author    : JokerTong
# Datetime  : 2023-01-16 14:41
# File      : chapter5.py
import cv2
import numpy as np

img = cv2.imread('Resources/cards.jpg')

width, height = 250, 350
src = np.float32([[111, 219], [287, 188], [154, 482], [352, 440]])
dst = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
matrix = cv2.getPerspectiveTransform(src, dst)
imgOutput = cv2.warpPerspective(img, matrix, (width, height))

cv2.imshow('Image', img)
cv2.imshow('Output', imgOutput)
cv2.waitKey(0)

主要使用cv2.getPerspectiveTransformcv2.warpPerspective两个函数

  • cv2.getPerspectiveTransform根据图像中不共线的 4 个点在变换前后的对应位置求得 (3x3) 变换矩阵
  • cv2.warpPerspective使用该 (3x3) 变换矩阵即可求出变换后的图像。
    在这里插入图片描述
  • cv2.getPerspectiveTransform: 得到变换矩阵
    • src : 变换前图像四边形顶点坐标
    • dst: 变换后图像四边形顶点坐标

在这里插入图片描述

  • cv2.warpPerspective: 得到变换后的图片
    • src : 原始输入图像
    • M: 用getPerspectiveTransform求得的变换矩阵
    • dsize 输出图像的大小 width, height)

在这里插入图片描述

图像拼接

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np

img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 用numpy来拼接, 无法改变图像的大小, 并且channel相同才可以拼接
imgHor = np.hstack((img, img))
# imgHor = np.hstack((img, imgGray))  # 会发生报错 因为维度不同
imgVer = np.vstack((img, img))

cv2.imshow("Horizontal", imgHor)
cv2.imshow("Vertical", imgVer)
cv2.waitKey(0)

读入的img可以看成一个矩阵, 所以可以用numpy的函数来对矩阵进行拼接
但这样有着许多局限性 如图像太大超出显示范围, 只能对相同维度的进行拼接(彩色和灰色不能拼接)

在这里插入图片描述
这里引入一个函数stackImages, 只需要知道怎么使用就行

def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''

案例

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np


def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver


img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 用stackImages函数来进行拼接
imgStack1 = stackImages(0.5, ([img, imgGray, img], [img, img, img]))
imgStack2 = stackImages(0.5, ([img, imgGray, img]))
imgStack3 = stackImages(0.5, ([img], [img], [img]))
cv2.imshow('ImageStack1', imgStack1)
cv2.imshow('ImageStack2', imgStack2)
cv2.imshow('ImageStack3', imgStack3)
cv2.waitKey(0)

可以按行 按列 并且不同维度的拼接, 也可以修改图像显示时的大小

在这里插入图片描述

全部代码

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np


def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver


img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# # 用numpy来拼接, 无法改变图像的大小, 并且channel相同才可以拼接
# imgHor = np.hstack((img, img))
# # imgHor = np.hstack((img, imgGray))  # 会发生报错 因为维度不同
# imgVer = np.vstack((img, img))
# 
# cv2.imshow("Horizontal", imgHor)
# cv2.imshow("Vertical", imgVer)
# cv2.waitKey(0)

# 用stackImages函数来进行拼接
imgStack1 = stackImages(0.5, ([img, imgGray, img], [img, img, img]))
imgStack2 = stackImages(0.5, ([img, imgGray, img]))
imgStack3 = stackImages(0.5, ([img], [img], [img]))
cv2.imshow('ImageStack1', imgStack1)
cv2.imshow('ImageStack2', imgStack2)
cv2.imshow('ImageStack3', imgStack3)
cv2.waitKey(0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch7.8.0版本入门——JavaAPI操作(环境准备)

目录一、创建springboot项目二、pom.xml文件引入相关maven依赖三、创建客户端对象一、创建springboot项目 创建springboot项目步骤参考此博文链接:https://wwwxz.blog.csdn.net/article/details/91977374 二、pom.xml文件引入相关maven依赖 引入elasticsearch依赖…

NR PUSCH(七) 相干传输

微信同步更新欢迎关注同名mode协议笔记 这篇就是为记录一个概念在协议中的体现方式。相干传输被定义为一种UE能力。考虑到UE的实现成本,NR不要求所有的UE都能做到所有的天线端口都可以相干传输。NR定义了以下3种UE的相干传输能力。 (1)全相干(Fully-coh…

正点原子Linux驱动第三期

目录 第一讲 系统镜像烧写 第二讲 u-boot编译 第三讲 uboot命令使用 第四讲 Uboot源码分析 第五讲 uboot顶层 Makefile分析 第六讲 Uboot启动流程 第七讲 uboot移植 第八讲 UBoot图形化界面配置 第九讲 Linux 内核移植 第十讲 Linux内核源码目录分析 第十一讲 Linux…

六、python操作mysql篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频:https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 下载pymysql 2. 新建数据库 3. mysql服务器版本查询 4. 执行非查询性质的SQL 5. 执行查询性质的sql 6. 执行新增sql 1. 下载pymysql 右下角点击版本 选择解释器设置 点击加号 搜…

Python(for和while)循环嵌套及用法

Python 不仅支持 if 语句相互嵌套,while 和 for 循环结构也支持嵌套。所谓嵌套(Nest),就是一条语句里面还有另一条语句,例如 for 里面还有 for,while 里面还有 while,甚至 while 中有 for 或者 …

无需下载就能使用的图像编辑器?能代替 Photoshop 吗?#Photopea

一款在线就能使用的图像编辑器,好用?还免费?Photopea 图源: Photopea 官网Photopea 可以处理光栅图形和矢量图形。您可以将它用于简单的任务,例如调整图像大小,也可以用于复杂的任务,例如设计网页、创建插图…

Day05 - 内置函数和参数

0. 列表 推导式 格式: 列表变量 [表达式 for 变量 in range(10)] 表达式中需要使用后面的变量 列表推导 式 创建一个具有一百个数字的列表 # c_l [] # for i in range(100): # c_l.append(i)# 使用列表推导式来完成列表的创建 c_l [i for i in range(100)] # c_l [x f…

macOS Ventura 13.2 (22D49) 正式版发布,ISO、IPSW、PKG 下载

macOS Ventura 13 正式版现已发布! 请访问原文链接:https://sysin.org/blog/macOS-Ventura/,查看最新版。原创作品,转载请保留出处。 2023 年 1 月 23 日(北京时间 24 日凌晨),macOS Ventura 1…

新年快乐—数睿通2.0数据中台全新功能模块发布

文章目录引言数据集成数据库管理文件管理数据接入贴源数据数据开发数据生产sql 作业开发FlinkSql 作业开发调度中心运维中心资源中心配置中心其他模块结语引言 离上次发文已经有接近三个月了,这三个月主要在开发数睿通的数据生产模块,同时优化了一下数据…

网络实验之EIGRP协议

一、EIGRP协议简介 EIGRP:Enhanced Interior Gateway Routing Protocol 即 增强内部网关路由协议。也翻译为 加强型内部网关路由协议。 EIGRP是Cisco公司的私有协议(2013年已经公有化)。 EIGRP结合了链路状态和距离矢量型路由选择协议的Cisco专用协议&am…

【LeetCode】二叉树的序列化与反序列化 [H](二叉树)

297. 二叉树的序列化与反序列化 - 力扣(LeetCode) 一、题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采…

【SpringCloud】Nacos注册中心、配置中心用法与原理(下)

【SpringCloud】Nacos注册中心、配置中心用法与原理(下) 上集回顾 二、Nacos 配置中心 1. 统一配置管理 (1)在 Nacos 中添加配置文件 (2)从微服务拉取配置 2. 配置热更新 方式一:使用 Re…

华为鸿蒙2.0如何安装谷歌服务框架

第一步: 如果安装过Google套件需要先卸载原有Google套件,设置-应用和服务-应用管理,搜索Google、谷歌等,原有谷歌套件全部卸载掉。(注意,要点击右上角打开“显示系统应用”,未安装过可以直接略过) 第二步:下载鸿蒙文件包(自行找资源下载) 1.打开(1.准备)把里面的…

项目2:使用Yolov5和deepsort实现车辆和行人目标跟踪,实时计算目标运动速度和加速度(有检测超速功能)

项目演示视频 项目演示视频可以跳转到哔哩哔哩观看:https://www.bilibili.com/video/BV1RT411Z7kD/?vd_source805c57038e291405fe38f3adefa0f2d2 项目简介 本项目使用Yolov5DeepSort实现车辆、行人跟踪,并实时统计各类别目标数量,以及测量…

人大金仓数据库的库、模式、表空间之间的关系

库、模式、表空间之间的关系 KES数据库结构图 列出集簇现有的数据库清单 \l 默认数据库的作用介绍 数据库定义以及相关操作 创建数据库并设置参数 设置属主、编码、参照模板template0、连接数为0 create database 数据库名 owner 属主用户名 template template0 encoding …

【二叉搜索树】BST相关题目

BST相关题目二叉搜索树中的众树二叉搜索树节点最小距离两数之和 IV - 输入二叉搜索树总结二叉搜索树中的众树 501.二叉搜索树中的众树 解题思路:中序遍历二叉搜索树,使得结果集是有序的,过程中将众数个数保存下来。利用两个变量&#xff0c…

Java---微服务---SpringCloud(2)

SpringCloud021.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置1.2.配置热更新1.2.1.方式一1.2.2.方式二1.3.配置共享1)添加一个环境共享配置2)在user-service中读取共享配置3)运行两个UserApplication&am…

域环境搭建

内网渗透基础——域环境搭建 第一步,配置IP地址 1.打开网络和共享中心 2.更改适配器设置 3.进入网络连接后,设置网卡属性 4.双击进入,修改IP地址 5.使用IP地址如下,IP地址设置为:192.168.1.1;子网掩码设置为:255.255.255.0;DNS属性设置为:192.168.1.1 6.设置好之后确…

Fisco Bcos区块链一(搭建单群组FISCO BCOS联盟链)

文章目录区块链开荒技术文档:https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/index.html推荐准备:1. 搭建单群组FISCO BCOS联盟链安装依赖创建操作目录, 下载安装脚本搭建单群组4节点联盟链启动FISCO BCOS链检查进程检查日志输出区块链开…

我的第一次真实对国外某购物平台web漏洞挖掘

(真实世界)我的第一次真实对国外某购物平台web漏洞挖掘 开放重定向 - 低危XSS - 低危 这两组合起来就完全不一样一点的,个人觉得比原本高一些 危害:窃取用户敏感数据、用户cookie、钓鱼操作 等… 前言 这是我第一次&#xff…