基于OpenCV的图像翻转和镜像

我们将解释如何在Python中实现图像的镜像或翻转。大家只需要了解各种矩阵运算和矩阵操作背后的基本数学即可。

01. 依赖包要求

NumPy —用于矩阵运算并对其进行处理。

OpenCV —用于读取图像并将其转换为2D数组(矩阵)。

Matplotlib —用于将矩阵绘制为图像。

图片

对于这个小型项目,我使用了著名的Lena图像,该图像主要用于测试计算机视觉模型。确保下载此映像并将其保存在当前工作目录中。

import cv2
import numpy as np
from matplotlib import pyplot as plt

02. 让我们开始吧

首先,我们使用imread()模块中的方法读取图像文件cv2。为此,我们只需要导入包并使用它即可。因此,通过这样做,我们获得了矩阵形式的图像。默认情况下,imread()该方法读取的图像BGR(Blue,Green,Red)格式。要读取的图像转换为常规格式,即,RGB(Red,Green,Blue),我们使用cvtColor()来自同一模块的方法cv2。

def read_this(image_file, gray_scale=False):image_src = cv2.imread(image_file)if gray_scale:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)else:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2RGB)return image_rgb

上面的函数从传递的图像文件返回图像矩阵。如果我们要获取图像矩阵或格式,它由常规if和else条件组成。

镜像图像

要基本镜像图像,我们需要从左到右逐行反转矩阵。让我们考虑一个matrix A。

>>> A = [[4, 1, 1],[2, 8, 0],[3, 8, 1]
]

如果我们要镜像此矩阵(逐行),则它将是-

>>> import numpy as np
>>> mirror_ = np.fliplr(A)
>>> mirror_
[[1, 1, 4],[0, 8, 2],[1, 8, 3]]

我们也可以在不使用NumPy模块的情况下执行此操作。如果是这样,我们可以使用循环并反转每一行。如果在图像矩阵上执行相同的操作将花费一些时间,因为它们是非常大的矩阵,并且我们不希望我们的代码执行得非常慢。

def mirror_this(image_file, gray_scale=False, with_plot=False):image_rgb = read_this(image_file=image_file, gray_scale=gray_scale)image_mirror = np.fliplr(image_rgb)if with_plot:fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text("Mirrored")if not gray_scale:ax1.imshow(image_rgb)ax2.imshow(image_mirror)else:ax1.imshow(image_rgb, cmap='gray')ax2.imshow(image_mirror, cmap='gray')return Truereturn image_mirror

上面的函数返回一个图像矩阵,该矩阵从左向右逐行反转或翻转。

让我们绘制相同的内容-

mirror_this(image_file="lena_original.png", with_plot=True)

图片

mirror_this(image_file="lena_original.png", gray_scale=True, with_plot=True)

图片

翻转图像

要基本翻转图像,我们需要将矩阵从上到下逐列反转。让我们考虑一个matrix B。

>>> B = [[4, 1, 1],[2, 8, 0],[3, 8, 1]
]

如果我们要翻转此矩阵(按列),则它将是-

>>> import numpy as np
>>> flip_= np.flipud(B)
>>> flip_
[[3, 8, 1],[2, 8, 0],[4, 1, 1]]

我们NumPy用于翻转矩阵以保持代码的牢固性。

def flip_this(image_file, gray_scale=False, with_plot=False):image_rgb = read_this(image_file=image_file, gray_scale=gray_scale)image_flip = np.flipud(image_rgb)if with_plot:fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text("Flipped")if not gray_scale:ax1.imshow(image_rgb)ax2.imshow(image_flip)else:ax1.imshow(image_rgb, cmap='gray')ax2.imshow(image_flip, cmap='gray')return Truereturn image_flip

上面的函数返回一个图像矩阵,该矩阵从上向下向下按列反转或翻转。

让我们绘制相同的内容-

flip_this(image_file='lena_original.png', with_plot=True)

图片

flip_this(image_file='lena_original.png', gray_scale=True, with_plot=True)

图片

完整的代码

class ImageOpsFromScratch(object):def __init__(self, image_file):self.image_file = image_filedef read_this(self, gray_scale=False):image_src = cv2.imread(self.image_file)if gray_scale:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2GRAY)else:image_rgb = cv2.cvtColor(image_src, cv2.COLOR_BGR2RGB)return image_rgbdef mirror_this(self, with_plot=True, gray_scale=False):image_rgb = self.read_this(gray_scale=gray_scale)image_mirror = np.fliplr(image_rgb)if with_plot:self.plot_it(orig_matrix=image_rgb, trans_matrix=image_mirror, head_text='Mirrored', gray_scale=gray_scale)return Nonereturn image_mirrordef flip_this(self, with_plot=True, gray_scale=False):image_rgb = self.read_this(gray_scale=gray_scale)image_flip = np.flipud(image_rgb)if with_plot:self.plot_it(orig_matrix=image_rgb, trans_matrix=image_flip, head_text='Flipped', gray_scale=gray_scale)return Nonereturn image_flipdef plot_it(self, orig_matrix, trans_matrix, head_text, gray_scale=False):fig = plt.figure(figsize=(10, 20))ax1 = fig.add_subplot(2, 2, 1)ax1.axis("off")ax1.title.set_text('Original')ax2 = fig.add_subplot(2, 2, 2)ax2.axis("off")ax2.title.set_text(head_text)if not gray_scale:ax1.imshow(orig_matrix)ax2.imshow(trans_matrix)else:ax1.imshow(orig_matrix, cmap='gray')ax2.imshow(trans_matrix, cmap='gray')return TrueRUBY 复制 全屏

基本图像操作包

imo = ImageOpsFromScratch(image_file='lena_original.png')
### Mirroring ###
imo.mirror_this()
imo.mirror_this(gray_scale=True)
### Flipping ###
imo.flip_this()
imo.flip_this(gray_scale=True)

将显示以上图像结果。现在,所有内容都已排序,我们可以创建其他图像操作,例如equalize(),solarize()等等。

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

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

相关文章

react setState调用为什么会触发整个组件函数的重新运行

react setState调用为什么会触发整个组件函数的重新运行例如下面的代码 function App(){const [age,setAge]useState(5);const clickHandler()>{setAge(5)}console.log("点击div时候&#xff0c;我也会被刷新")return (<div onClick{clickHandler}><di…

【LeetCode:228. 汇总区间 | 区间】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

分析抖音直播弹幕评论和礼物的websocket数据流信息,通过proto协议解析消息内容思路

现在定位到一个解析的大概位置&#xff1a; e.decode function(e, t) {e instanceof o || (e o.create(e));for (var n, i, s void 0 t ? e.len : e.pos t, u new r.webcast.im.MemberMessage(r.webcast. 通过请求找到发送请求的js代码位置&#xff0c;然后通过跟踪这…

【远程计算机,这可能是由于 Credssp 加客数据库修正】解决方案

1、winR打开运行窗口 输入gpedit.msc命令&#xff0c;若找不到&#xff0c;可以进行如下文件编辑格式为cmd echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txtdir /b C:\Win…

centos通过yum 安装nginx和基本操作

Yum安装Nginx 1、配置Centos 7 Nginx Yum源仓库(注意系统版本要匹配&#xff0c;此步根据环境来确认&#xff0c;不是必须的&#xff09; rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 2、安装Nginx yum install n…

宏基因组序列无参考基因组装工具idba-ud的介绍及详细使用方法

介绍 idba-ud工具是一种用于组装无参考基因组的工具&#xff0c;它可以将高通量测序数据转化为基因组序列。它是idba工具的升级版本&#xff0c;专门用于组装多样性的无参考基因组。 idba-ud的主要作用是通过组装测序数据&#xff0c;生成无参考基因组的序列。它能够处理短读…

C#中List<T>底层原理剖析

C#中List底层原理剖析 1. 基础用法2. List的Capacity与Count&#xff1a;3.List的底层原理3.1. 构造3.2 Add()接口3.3 Remove()接口3.4 Inster()接口3.5 Clear()接口3.6 Contains()接口3.7 ToArray()接口3.8 Find()接口3.8 Sort()接口 4. 总结5. 参考 1. 基础用法 list.Max() …

【tkinter 电子时钟 实现时间日期 可实现透明 无标题栏】

下面是一个使用tkinter实现的简单的电子时钟&#xff0c;包括时间和日期的显示。该窗口是透明的&#xff0c;没有标题栏。 效果&#xff1a; import tkinter as tk from datetime import datetimedef update_time():now datetime.now()time_label.configure(textnow.strftim…

CSS效果(工作中常用)

1、css文字溢出省略号 overflow: hidden; // 溢出隐藏 text-overflow: ellipsis; // 溢出用省略号显示 white-space: nowrap; // 规定段落中的文本不进行换行 overflow: hidden; // 溢出隐藏 text-overflow: ellipsis; // 溢出用省略…

labelme的json转mask,实测有效

1、创建一个conda的虚拟环境 conda creat -n labelme python3.82、转到你的标注文件夹&#xff08;包括json和图片&#xff09; cd C:/Users/Administrator/Desktop/json3、你需要在标注文件夹下用txt写下以下代码&#xff0c;并保存bat文件。 放在最后一个就可以了 echo of…

JSON和AJAX

AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一种无需重新加载整个页面就能更新部分网页的技术。它使用JavaScript的XMLHttpRequest对象来发送异步请求&#xff0c;并获取服务器响应。AJAX可以用于在不刷新页面的情况下更新网页内容、与服务器交换数据并更新…

while猜数字实例——C++版

案例描述&#xff1a;系统随机生成一个1到100之间的数字&#xff0c;玩家进行猜测&#xff0c;如果猜错&#xff0c;提示玩家数字过大或过小&#xff0c;如果猜对恭喜玩家胜利并退出游戏。 逻辑框图&#xff1a; #include<bits/stdc.h> using namespace std; int main()…

如何在GitHub正确提PR(Pull Requests),给喜欢的开源项目贡献代码

最好的中文TTS项目Bert-vits2更新了中文特化分支&#xff0c;但可能由于时间仓促&#xff0c;代码中存在不少的bug&#xff0c;作为普通用户&#xff0c;有的时候也想为自己喜欢的开源项目做一点点贡献&#xff0c;帮助作者修改一些简单的bug&#xff0c;那么该如何开始&#x…

Vert.x学习笔记-什么是事件总线

广义事件总线介绍Vert.x的事件总线Vert.x的事件总线的实现方式Vert.x的事件总线通信模式事件总线与消息队列的区别点对点通信模式请求-应答通信模式发布-订阅通信模式 Vert.x的事件总线应用场景Vert.x的事件总线消息Vert.x的事件总线消息示例Vert.x的事件总线的消息类型 拓展 广…

【Spark精讲】SparkSQL Join选择逻辑

SparkSQL Join选择逻辑 先看JoinSelection的注释 If it is an equi-join, we first look at the join hints w.r.t. the following order: 1. broadcast hint: pick broadcast hash join if the join type is supported. If both sides have the broadc…

四、C#高级特性(动态类型与Expando类)

在C#中&#xff0c;动态类型和ExpandoObject类是两个与运行时类型系统相关的特性&#xff0c;它们提供了更灵活的数据处理能力。 动态类型 动态类型是一种特殊的类型&#xff0c;允许你在运行时解析和操作对象的成员&#xff0c;而不需要在编译时知道这些成员的细节。使用动态…

通讯录排序(结构体)

输入n个朋友的信息&#xff0c;包括姓名、生日、电话号码&#xff0c;本题要求编写程序&#xff0c;按照年龄从大到小的顺序依次输出通讯录。题目保证所有人的生日均不相同。 输入格式: 输入第一行给出正整数n&#xff08;<10&#xff09;。随后n行&#xff0c;每行按照“…

【设计模式】解释器模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 四、优缺点 五、使用场景 总结 前言 【设计模式】——行为型模式。 一、概述 如上图&#xff0c;设计一个软件用来进行加减计算。我们第一想法就是使用工具类&#xff0c;提供对应的加法和减法的工具方法。 …

vue2中vuex详细使用

1.安装 说明&#xff1a;也就是版本号&#xff0c;一般vue2安装vuex3。 npm i vuex3.6.2 2.搭建架子 执行流程如下&#xff1a; 初始化状态&#xff1a;在state对象中定义了一个名为message的属性&#xff0c;并将其初始值设置为"启动"。 定义变更函数&#xff08…

Kafka(六)消费者

目录 Kafka消费者1 配置消费者bootstrap.serversgroup.idkey.deserializervalue.deserializergroup.instance.idfetch.min.bytes1fetch.max.wait.msfetch.max.bytes57671680 (55 mebibytes)max.poll.record500max.partition.fetch.bytessession.timeout.ms45000 (45 seconds)he…