【OpenCV3】图像的翻转、图像的旋转、仿射变换之图像平移、仿射变换之获取变换矩阵、透视变换

1 图像的放大与缩小
2 图像的翻转
3 图像的旋转
4 仿射变换之图像平移
5 仿射变换之获取变换矩阵
6 透视变换

1 图像的放大与缩小

  • resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

    • src: 要缩放的图片
    • dsize: 缩放之后的图片大小, 元组和列表表示均可.
    • dst: 可选参数, 缩放之后的输出图片
    • fx, fy: x轴和y轴的缩放比, 即宽度和高度的缩放比.
    • interpolation: 插值算法, 主要有以下几种:
      • INTER_NEAREST, 邻近插值, 速度快, 效果差.
      • INTER_LINEAR, 双线性插值, 使用原图中的4个点进行插值. 默认.
      • INTER_CUBIC, 三次插值, 原图中的16个点.
      • INTER_AREA, 区域插值, 效果最好, 计算时间最长.
import cv2  # 导入OpenCV库,用于图像处理
import numpy as np  # 导入NumPy库,用于处理数组操作# 读取图片文件,将它们分别加载到变量dog和cat中
dog = cv2.imread('./dog.jpeg')  # 加载狗的图像
cat = cv2.imread('./cat.jpeg')  # 加载猫的图像# 打印图像的形状,确保正确加载图像,并了解它们的尺寸
print(dog.shape)  # 输出:狗的图像尺寸 (360, 499, 3) - 3代表RGB通道
print(cat.shape)  # 输出:猫的图像尺寸 (480, 640, 3) - 3代表RGB通道# 将猫的图像调整为与狗的图像相同的大小
new_cat = cv2.resize(cat, (499, 360))  # 将猫的图像大小缩放至 (499, 360)# 使用不同的插值方法将狗的图像缩放到800x800像素
# # 1. 最近邻插值(INTER_NEAREST):这是最简单的插值方法,直接选择最近的像素。通常会导致图像有较大的像素块感。
# new_dog1 = cv2.resize(dog, (800, 800), interpolation=cv2.INTER_NEAREST)# # 2. 双线性插值(INTER_LINEAR):常用的插值方法,考虑周围的像素并计算加权平均值。缩放效果较平滑,适用于图像放大。
# new_dog2 = cv2.resize(dog, (800, 800), interpolation=cv2.INTER_LINEAR)# # 3. 三次插值(INTER_CUBIC):相比于双线性插值更复杂的插值算法,使用16个周围的像素来计算新的像素值,图像放大时更平滑,但速度较慢。
# new_dog3 = cv2.resize(dog, (800, 800), interpolation=cv2.INTER_CUBIC)# # 4. 像素区域关系重采样(INTER_AREA):通常用于缩小图像,通过考虑像素区域的平均值来生成新的像素,适合于图像缩小时使用。
# new_dog4 = cv2.resize(dog, (800, 800), interpolation=cv2.INTER_AREA)# 打印缩放后的猫图像的数据(可以删除此行,除非需要调试)
# print(new_cat)  # 这会输出图像的像素矩阵值# 将狗和猫的图像水平拼接在一起并显示
cv2.imshow('new_cat', np.hstack((dog, new_cat)))  # np.hstack水平拼接两个图像
cv2.waitKey(0)  # 等待用户按任意键后继续(以显示窗口)
cv2.destroyAllWindows()  # 关闭所有打开的窗口

2 图像的翻转

  • flip(src, flipCode)
    • flipCode =0 表示上下翻转
    • flipCode >0 表示左右翻转
    • flipCode <0 上下 + 左右
# 翻转
import cv2
import numpy as np#导入图片
dog = cv2.imread('./dog.jpeg')new_dog = cv2.flip(dog, flipCode=-1)
cv2.imshow('dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()

3 图像的旋转

  • rotate(img, rotateCode)
    • ROTATE_90_CLOCKWISE 90度顺时针
    • ROTATE_180 180度
    • ROTATE_90_COUNTERCLOCKWISE 90度逆时针
# 旋转
import cv2
import numpy as np#导入图片
dog = cv2.imread('./dog.jpeg')new_dog = cv2.rotate(dog, rotateCode=cv2.cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imshow('dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()

4 仿射变换之图像平移

  • 仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 所以关键就是这个矩阵.

  • warpAffine(src, M, dsize, flags, mode, value)

  • M:变换矩阵

  • dsize: 输出图片大小

  • flag: 与resize中的插值算法一致

  • mode: 边界外推法标志

  • value: 填充边界值

  • 平移矩阵

    • 矩阵中的每个像素由(x,y)组成,(x, y)表示这个像素的坐标. 假设沿x轴平移 t x t_x tx​​​​​​​​, 沿y轴平移 t y t_y ty​​​​​​​, 那么最后得到的坐标为 ( x ^ , y ^ ) = ( x + t x , y + t y ) (\hat x, \hat y) = (x + t_x, y + t_y) (x^,y^)=(x+tx,y+ty)​​​​, 用矩阵表示就是:

在这里插入图片描述

# 仿射变换之平移
import cv2
import numpy as np#导入图片
dog = cv2.imread('./dog.jpeg')h, w, ch = dog.shape
M = np.float32([[1, 0, 100], [0, 1, 0]])
# 注意opencv中是先宽度, 再高度
new = cv2.warpAffine(dog, M, (w, h))cv2.imshow('new', new)
cv2.waitKey(0)
cv2.destroyAllWindows()

5 仿射变换之获取变换矩阵

仿射变换的难点就是计算变换矩阵, OpenCV提供了计算变换矩阵的API

  • getRotationMatrix2D(center, angle, scale)
    • center 中心点 , 以图片的哪个点作为旋转时的中心点.
    • angle 角度: 旋转的角度, 按照逆时针旋转.
    • scale 缩放比例: 想把图片进行什么样的缩放.
# 仿射变换之平移
import cv2
import numpy as np#导入图片
dog = cv2.imread('./dog.jpeg')h, w, ch = dog.shape
# M = np.float32([[1, 0, 100], [0, 1, 0]])# 注意旋转的角度为逆时针.
# M = cv2.getRotationMatrix2D((100, 100), 15, 1.0)
# 以图像中心点旋转
M = cv2.getRotationMatrix2D((w/2, h/2), 15, 1.0)
# 注意opencv中是先宽度, 再高度
new = cv2.warpAffine(dog, M, (w, h))cv2.imshow('new', new)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • getAffineTransform(src[], dst[]) 通过三点可以确定变换后的位置, 相当于解方程, 3个点对应三个方程, 能解出偏移的参数和旋转的角度.

    • src原目标的三个点

    • dst对应变换后的三个点

请添加图片描述

import cv2
import numpy as np# 导入图片
dog = cv2.imread('./dog.jpeg')  # 使用cv2.imread读取图片# 获取图片的高度(h),宽度(w),以及通道数(ch)
h, w, ch = dog.shape# 定义原始图片中用于仿射变换的三个顶点坐标
# 这三个点是仿射变换之前的点,指定用于计算仿射变换矩阵
src = np.float32([[20, 10], [30, 10], [20, 30]])# 定义变换后目标图片中对应的三个顶点坐标
# 这些点是原始图片中的三个点在仿射变换后的位置
dst = np.float32([[10, 15], [36, 20], [28, 10]])# 计算仿射变换矩阵
# cv2.getAffineTransform会根据src和dst的点计算出2x3的仿射变换矩阵M
M = cv2.getAffineTransform(src, dst)# 对原图像进行仿射变换
# cv2.warpAffine使用仿射变换矩阵M对图片进行仿射变换,输出图片大小为原图的宽(w)和高(h)
new_dog = cv2.warpAffine(dog, M, (w, h))# 显示仿射变换后的图片
cv2.imshow('new_dog', new_dog)# 等待键盘事件
cv2.waitKey(0)  # 等待按键事件,0表示无限等待
cv2.destroyAllWindows()  # 关闭所有窗口

6 透视变换

透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".

请添加图片描述

  • warpPerspective(img, M, dsize,…)

  • 对于透视变换来说, M是一个3 * 3 的矩阵.

  • getPerspectiveTransform(src, dst) 获取透视变换的变换矩阵, 需要4个点, 即图片的4个角.

import cv2
import numpy as np# 导入图片
img = cv2.imread('./123.png')  # 使用cv2.imread读取图片
print(img.shape)  # 打印图片的尺寸信息,返回的是(高, 宽, 通道数)# 定义源图像的四个顶点坐标
# 这些坐标是在原图像中的四个点,用于透视变换
src = np.float32([[100, 1100], [2100, 1100], [0, 4000], [2500, 3900]])# 定义目标图像的四个顶点坐标
# 这些坐标是透视变换后图像中对应的四个点
dst = np.float32([[0, 0], [2300, 0], [0, 3000], [2300, 3000]])# 计算透视变换矩阵
# 这个矩阵将源图像的四个点映射到目标图像的四个点
M = cv2.getPerspectiveTransform(src, dst)# 使用计算得到的透视变换矩阵进行图像变换
# cv2.warpPerspective将原图像按照透视矩阵M进行变换,输出尺寸为(2300, 3000)
new = cv2.warpPerspective(img, M, (2300, 3000))# 创建用于显示原图的窗口,并调整窗口大小
cv2.namedWindow('img', cv2.WINDOW_NORMAL)  # 创建窗口 'img'
cv2.resizeWindow('img', 640, 480)  # 将窗口 'img' 调整为640x480# 创建用于显示透视变换后的图像窗口,并调整窗口大小
cv2.namedWindow('new', cv2.WINDOW_NORMAL)  # 创建窗口 'new'
cv2.resizeWindow('new', 640, 480)  # 将窗口 'new' 调整为640x480# 显示原图和透视变换后的图像
cv2.imshow('img', img)  # 显示原图
cv2.imshow('new', new)  # 显示透视变换后的图像# 等待键盘事件
cv2.waitKey(0)  # 无限等待按键输入,0表示无限等待
cv2.destroyAllWindows()  # 关闭所有窗口

设计logo

  • 1.引入图片
  • 2.设计一个logo图片
  • 3.规划一个自己的logo,看看放哪里合适,在添加的位置变成黑色
  • 4.利用add方法,把logo和图片叠加在一起
import cv2
import numpy as npdog = cv2.imread('./dog.jpeg')# 创建logo
logo = np.zeros((200, 200, 3), np.uint8)# 绘制logo
logo[20: 120, 20: 120] = [0, 0, 255]
logo[80: 180, 80: 180] = [0, 255, 0]# 掩码
mask = np.zeros((200, 200), np.uint8)
mask[20: 120, 20: 120] = 255
mask[80: 180, 80: 180] = 255# cv2.imshow('mask', mask)
m = cv2.bitwise_not(mask)
# cv2.imshow('m', m)# 选择dog添加logo的位置
roi = dog[0: 200, 0: 200]# roi与m进行与操作, mask先roi,roi做与运算
tmp = cv2.bitwise_and(roi, roi, mask=m)
# cv2.imshow('tmp', tmp)dst = cv2.add(tmp, logo)
# cv2.imshow('dst', dst)# 在dog上还原
dog[: 200, : 200] = dst# cv2.imshow('logo', logo)
cv2.imshow('dog', dog)cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

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

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

相关文章

【无标题】XSS安全防护:responseBody (输入流可重复读) 配置

接上文:配置XSS过滤器 XXS 安全防护:拦截器+注解实现校验-CSDN博客XSS(跨站脚本)攻击是一种网络安全威胁,允许攻击者注入恶意脚本到看似安全的网站。当用户浏览这些被注入恶意代码的网页时,恶意脚本会在用户的浏览器环境中执行,这可能导致多种安全问题,如窃取敏感数据、…

将添加功能的抽屉剥离,在父组件调用思路

一、新建组件 新建AddRoleEditerDrawer.vue<template><div><el-drawer v-model"dialog" title"添加角色" :before-close"handleClose" direction"rtl" colse"cancelForm"class"demo-drawer" moda…

「数学::质数」试除法 / Luogu P5736(C++)

概述 在质数的第一节我们来讲解试除法。 质数是指在大于1的自然数中只能被1和它自己整除的数。 我们可以利用这一除法性质对质数进行判定。 Luogu P5736&#xff1a; 输入 n 个不大于 10^5 的正整数。要求全部储存在数组中&#xff0c;去除掉不是质数的数字&#xff0c;依…

LLM Attention and Rotary Position Embedding(旋转位置编码)

旋转位置编码&#xff08;Rotary Position Embedding&#xff0c;RoPE&#xff09;是一种能够将相对位置信息依赖集成Attention计算里的方法。就是在做词表映射的时候不是单一的进行一个embedding计算&#xff0c;还考虑位置信息。 一些资料 [1] https://arxiv.org/pdf/2104.0…

面对养老困局我心安若素

“2025年&#xff0c;我们需要注意什么&#xff1f;是复杂的国际环境么&#xff1f;明年对于我国70岁以上的老年人来说这可不是主要关心的问题。反而有这两件事情需要他们来关注&#xff0c;如果70岁老人不提前做好准备&#xff0c;可能会有非常严重的后果......”这是昨天发表…

鸿蒙轻内核M核源码分析系列十五 CPU使用率CPUP

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 轻内核M核源码分析系列一 数据结构-双向循环链表 轻内核M核源码分析系列二 数据结构-任务就绪队列 鸿蒙轻内核M核源码分析系列三 数据结构-任务排序链表 轻…

国产脑机全面超越马斯克Nearlink

&#x1f4a5;&#x1f4a5;&#x1f4a5;刚刚&#xff0c;世界首富马斯克同学已经是完全懵逼了&#xff0c;心态都崩了&#xff01;因为今天爆出来了一个轰动了全世界科技界的大新闻&#xff0c;国产脑机在多个维度上全面超越了马斯克的Nearlink&#xff01; &#x1f4a5;&am…

SpringBoot2:请求处理原理分析-RESTFUL风格接口

一、RESTFUL简介 Rest风格支持&#xff08;使用HTTP请求方式&#xff0c;动词来表示对资源的操作&#xff09; 以前&#xff1a;/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户 现在&#xff1a; /user GET-获取用户 DELETE-删除用户 PUT-修改…

数据仓库技术选型方案文档

关联博客&#xff1a; 数据仓库技术选型方案文档 Flink CDC MySQL数据同步到Doris表同步配置生成工具类 新版报表系统&#xff08;明细报表、看板、数据大屏&#xff09;方案&介绍 文章目录 数据仓库技术选型背景现状现状架构目标架构业务反馈&痛点问题&#xff1a;原因…

随手记:小程序体积超出2M包大小如何优化

小程序的包体积限制是2M&#xff0c;超出包大小如何优化 先简单列出&#xff0c;最近比较忙&#xff0c;后续优化明细&#xff0c;有着急的先留言踢我 1.分包 留几个主要的页面体积小的&#xff0c;剩下的在page.json中拆到subpackages中&#xff0c;简单举个例子 "page…

多维动态规划-面试高频!-最长公共子序列和最长公共子串、回文串-c++实现和详解

1143. 最长公共子序列 中等 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删…

力扣1049-最后一块石头的重量II(Java详细题解)

题目链接&#xff1a;1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 最近刚学完01背包&#xff0c;所以现在的题解都是以01背包问题为基础再来写的。 如果大家不懂…

FPGA实现串口升级及MultiBoot(二)FPGA启动流程

这个系列开篇肯定要先了解FPGA的启动流程&#xff0c;试想一下&#xff1a;我想实现MultiBoot&#xff0c;那么我应该在什么时候开始升级&#xff0c;升级失败后FPGA进行了哪些操作&#xff0c;以及怎么回到Golden区&#xff1f; 还有一个问题&#xff0c;就是我硬件打板回来&a…

Selenium 实现图片验证码识别

前言 在测试过程中&#xff0c;有的时候登录需要输入图片验证码。这时候使用Selenium进行自动化测试&#xff0c;怎么做图片验证码识别&#xff1f;本篇内容主要介绍使用Selenium、BufferedImage、Tesseract进行图片 验证码识别。 环境准备 jdk&#xff1a;1.8 tessdata&…

深度学习--对抗生成网络(GAN, Generative Adversarial Network)

对抗生成网络&#xff08;GAN, Generative Adversarial Network&#xff09;是一种深度学习模型&#xff0c;由Ian Goodfellow等人在2014年提出。GAN主要用于生成数据&#xff0c;通过两个神经网络相互对抗&#xff0c;来生成以假乱真的新数据。以下是对GAN的详细阐述&#xff…

如果电脑一直提示微软账号登录……

前言 今天小白接了个电脑故障问题&#xff1a;电脑提示微软账号登录&#xff0c;然后经过各种操作…… 电脑重启之后就变成了这样&#xff1a; 按理说&#xff0c;登录了微软账号之后&#xff0c;Windows系统要进入到桌面就必须有一个输入密码验证的过程&#xff0c;但这个界…

Harmony OS DevEco Studio 如何导入第三方库(以lottie为例)?-- HarmonyOS自学2

在做鸿蒙开发时&#xff0c;离不开第三方库的引入 一.有哪些支持的Harmony OS的 第三方库&#xff1f; 第三方库下载地址&#xff1a; 1 tpc_resource: 三方组件资源汇总 2 OpenHarmony三方库中心仓 二. 如何加入到DevEco Studio工程 以 lottie为例 OpenHarmony-TPC/lot…

nginx 新建一个 PC web 站点

注意&#xff1a;进行实例之前必须完成nginx的源码编译。&#xff08;阅读往期文章完成步骤&#xff09; 1.编辑nginx的配置文件&#xff0c;修改内容 [rootlocalhost ~]# vim /usr/local/nginx/conf/nginx.conf 2.创建新目录/usr/local/nginx/conf.d/&#xff0c;编辑新文件…

基于飞腾平台的Hive的安装配置

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

通信工程学习:什么是PCM脉冲编码调制、DPCM差分脉冲编码调制、ADPCM自适应差分脉冲编码调制

PCM脉冲编码调制、DPCM差分脉冲编码调制、ADPCM自适应差分脉冲编码调制 PCM、DPCM、ADPCM是音频编码技术中的三种重要方式&#xff0c;它们在音频信号的数字化、压缩和传输中起着关键作用。以下是对这三种技术的详细解释&#xff1a; 一、PCM&#xff08;Pulse Code Modulatio…