使用numpy处理图片——镜像翻转和旋转

news2024/11/19 11:15:58

在《使用numpy处理图片——基础操作》一文中,我们介绍了如何使用numpy修改图片的透明度。本文我们将介绍镜像翻转和旋转。

镜像翻转

上下翻转

在这里插入图片描述

from PIL import Image
import numpy as np
img = Image.open('example.png')
data = np.array(img)

# axis=0 is vertical, axis=1 is horizontal
verticalData = np.flip(data, axis=0)
verticalImg = Image.fromarray(verticalData)
verticalImg.save('vertical.png')

请添加图片描述

左右翻转

在这里插入图片描述

from PIL import Image
import numpy as np
img = Image.open('example.png')
data = np.array(img)

# axis=0 is vertical, axis=1 is horizontal
horizontalData = np.flip(data, axis=1)
horizontalImg = Image.fromarray(horizontalData)
horizontalImg.save('horizontal.png')

请添加图片描述

旋转

上面的翻转,又可以称之为镜像翻转。因为得到的图片,只有通过镜子去查看,才是正常的字。

在这里插入图片描述
而一般情况下,我们需要的是旋转,即得到的文字还是可以正确识别的。
在这里插入图片描述

向左旋转90度

向左旋转90需要通过两个步骤完成:

  1. 转置
  2. 上下镜像翻转
    在这里插入图片描述
def flip_left_90(arr):
    return np.flip(arr.transpose((1,0,2)), axis=0)

需要解释下transpose传递元组的意思

If specified, it must be a tuple or list which contains a permutation of [0,1,…,N-1] where N is the number of axes of a. The i’th axis of the returned array will correspond to the axis numbered axes[i] of the input. If not specified, defaults to range(a.ndim)[::-1], which reverses the order of the axes.

这句话的意思是,传递的元组要包含该数组所有的维度的值。转换的方法就是对应项相互转置。比如数组最开始时的维度表示是(0,1,2),如果给transpose传递了(1,0,2)。就意味着0维度和1维度转置,2维度保持不变。这个对我们处理图片特别重要,因为2维度保存的是RGBA信息。这个信息不能转置,否则就会导致颜色错乱。
请添加图片描述

旋转180度

旋转180度有两种方法:

  1. 两次90度左转。
  2. 上下镜像翻转后左右镜像翻转。(顺序无所谓)

在这里插入图片描述

def flip_180_with_flip_left_90(arr):
    return flip_left_90(flip_left_90(arr))

在这里插入图片描述

def flip_180_with_axis(arr):
    return np.flip(np.flip(arr, axis=1), axis=0)

请添加图片描述

向右旋转90度

向右旋转90度,也是向左旋转270度。可以拆解为:

  • 3次向左旋转
  • 1次180度旋转外加1次90度向左旋转
  • 1次90度向左旋转外加1次180度旋转
def flip_right_90_with_left_90(arr):
    return flip_left_90(flip_left_90(flip_left_90(arr)))

def flip_right_90_with_axis_left_90(arr):
    return flip_left_90(flip_180_with_axis(arr))

def flip_right_90_with_left_90_axis(arr):
    return flip_180_with_axis(flip_left_90(arr))

请添加图片描述

代码

from PIL import Image
import numpy as np
img = Image.open('example.png')
data = np.array(img)

# axis=0 is vertical, axis=1 is horizontal
verticalData = np.flip(data, axis=0)
verticalImg = Image.fromarray(verticalData)
verticalImg.save('vertical.png')

horizontalData = np.flip(data, axis=1)
horizontalImg = Image.fromarray(horizontalData)
horizontalImg.save('horizontal.png')

def flip_180_with_flip_left_90(arr):
    return flip_left_90(flip_left_90(arr))

def flip_180_with_axis(arr):
    return np.flip(np.flip(arr, axis=1), axis=0)

def flip_left_90(arr):
    return np.flip(arr.transpose((1,0,2)), axis=0)

def flip_right_90_with_left_90(arr):
    return flip_left_90(flip_left_90(flip_left_90(arr)))

def flip_right_90_with_axis_left_90(arr):
    return flip_left_90(flip_180_with_axis(arr))

def flip_right_90_with_left_90_axis(arr):
    return flip_180_with_axis(flip_left_90(arr))

left90Data = flip_left_90(data)
left90Img = Image.fromarray(left90Data)
left90Img.save('flipleft90.png')

right90DataFromLeft90 = flip_right_90_with_left_90(data)
right90ImgFromLeft90 = Image.fromarray(right90DataFromLeft90)
right90ImgFromLeft90.save('flipright90fromleft90.png')

right90DataFromAxisLeft90 = flip_right_90_with_axis_left_90(data)
right90ImgFromAxisLeft90 = Image.fromarray(right90DataFromAxisLeft90)
right90ImgFromAxisLeft90.save('flipright90fromamxisleft90.png')

right90DataFromLeft90Axis = flip_right_90_with_left_90_axis(data)
right90ImgFromLeft90Axis = Image.fromarray(right90DataFromLeft90Axis)
right90ImgFromLeft90Axis.save('flipright90fromleft90amxis.png')

left180DataFromLeft90 = flip_180_with_flip_left_90(data)
left180ImgFromLeft90 = Image.fromarray(left180DataFromLeft90)
left180ImgFromLeft90.save('flip180fromleft90.png')

left180DataFromAxis = flip_180_with_axis(data)
left180ImgFromAxis = Image.fromarray(left180DataFromAxis)
left180ImgFromAxis.save('flip180fromaxis.png')

参考资料

  • https://flat2010.github.io/2017/05/31/Numpy%E6%95%B0%E7%BB%84%E8%A7%A3%E6%83%91/
  • https://numpy.org/doc/stable/reference/generated/numpy.transpose.html

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

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

相关文章

B端产品经理学习-权限管理

目录 权限管理的原则 常见的权限管理模型 总结 对企业而言,最重要的一个资源就是有价值的专有信息,也就是自己知道,而其他企业不知道的信息,因此,专有信息是企业的重要竞争力,权限管理的价值体现在专有信…

Spring基于注解的AOP控制事务

首先在.xml中开启sprong对注解事务的支持 applicationContext.xml <tx:annotation-driven transaction-manager"transactionManager"/> 然后再Service中加上注解 service Service Transactional(readOnlytrue,propagation Propagation.SUPPORTS) public cl…

【Java集合篇】HashMap的remove方法是如何实现的?

HashMap的remove方法是如何实现的 ✔️典型解析✔️拓展知识仓✔️HashMap的remove方法的注意事项✔️HashMap的remove方法的参数类型✔️ 删除键和值的参数类型有什么区别✔️删除键值对的场景是什么 ✔️HashMap remove方法是阻塞队列的吗✔️HashMap remove方法是线程安全的…

行为型设计模式——模板方法模式

学习难度&#xff1a;⭐ &#xff0c;比较常用 模板方法模式 在面向对象程序设计过程中&#xff0c;程序员常常会遇到这种情况&#xff1a;设计一个系统时知道了算法所需的关键步骤&#xff0c;而且确定了这些步骤的执行顺序&#xff0c;但某些步骤的具体实现还未知&#xff0…

前端面试题集合七(ES6、ES7、ES8、ES9、ES10、ES11、ES12)

ES6&#xff08;2015&#xff09; 1. 类&#xff08;class&#xff09; class Man {constructor(name) {this.name 小豪;}console() {console.log(this.name);} } const man new Man(小豪); man.console(); // 小豪 2. 模块化(ES Module) // 模块 A 导出一个方法 export …

@FunctionalSpringBootTest 和@SpringBootTest注解的区别

FunctionalSpringBootTest 和 SpringBootTest 是Spring框架中用于测试的两个不同注解。下面是它们之间的主要区别&#xff1a; 用途和范围&#xff1a; SpringBootTest&#xff1a;这个注解用于需要测试Spring应用程序上下文的场合。它会加载完整的应用程序上下文&#xff0c;适…

AI教我学编程之C#入门程序详解与拓展

与AI肩并肩 前言一、一个简单的C#程序补充说明对话AI 二、标识符三、关键字四、Main五、空白1. 缩进2. 代码块的间距3. 操作符的空格4. 换行5. 一致性 六、语句七、从程序输出文本主题&#xff1a;从程序中输出文本1. Write 和 WriteLine 方法2. 格式字符串3. 多重标记和值4. 格…

阿里云国际服务器设置安全防护程序

阿里云云服务器&#xff08;ECS&#xff09;提供弹性、安全、高性能、高性价比的虚拟云服务器&#xff0c;满足您的所有需求。立即在这里免费注册&#xff01; 常见 Web 应用程序 请勿对 Web 服务控制台&#xff08;如 WDCP、TOMCAT、Apache、Nginx、Jekins、PHPMyAdmin、Web…

浅谈有源滤波在某棉纺企业低压配电室节能应用

叶根胜 安科瑞电气股份有限公司 上海嘉定 201801 0引言 在电力系统中&#xff0c;谐波的根本原因是非线性负载。由于电子设备、变频器、整流器等。在棉纺企业的大部分设备中被广泛使用&#xff0c;因此会产生大量的谐波电流。我公司的环锭纱线和筒车间的配电设备受到谐波的影…

【C语言】time.h——主要函数介绍(附有几个小项目)

time.h是C标准函数库中获取时间与日期、对时间与日期数据操作及格式化的头文件。返回值类型 size_t&#xff1a;适合保存sizeof的结果&#xff0c;类型为unsigned int&#xff08;%u&#xff09;clock_t&#xff1a;适合存储处理器时间的类型&#xff0c;一般为unsigned long&…

day 43动态规划(5)

day 43 代码随想录 2024.1.10 发烧中。。。简单过一遍等二刷DP问题&#xff01;&#xff08;最近赶一篇paper&#xff01;&#xff09; 1. 1049最后一块石头的重量 dp[j]表示容量&#xff08;这里说容量更形象&#xff0c;其实就是重量&#xff09;为j的背包&#xff0c;最多…

51单片机介绍

1 单片机简介 单片机&#xff0c;英文Micro Controller Unit&#xff0c;简称MCU 内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能 单片机的任务是信息采集&#xff08;依靠传感器&#xff09;、处理&#xff08;依靠CPU&#xff09;和硬件设…

基于JavaWeb+BS架构+SpringBoot+Vue校园一卡通系统的设计和实现

基于JavaWebBS架构SpringBootVue校园一卡通系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 第一章 概述 4 1.1 研究背景 4 1.2研究目的及意义 4 1.3国内外发展现状 4 1…

DePIN:重塑物理资源网络的未来

点击查看TechubNews更多相关推荐 一、DePIN&#xff1a;物理资源的新整合方式 Depin赛道的项目如雨后春笋般涌现&#xff0c;为市场注入了新的活力。作为先行者&#xff0c;Coinmanlabs已经深入布局Depin赛道&#xff0c;其中最引人注目的项目当属Grass。 什么是DePIN DePIN…

Java项目:114SSM图书管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 图书管理系统基于SpringSpringMVCMybatis开发&#xff0c;系统主要实现了图书馆借书还书功能&#xff0c;系统分为管理员和读者两种角色。 管理员功能如下…

A股风格因子看板 (2024.01 第4期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴 露等。 今日为该因子跟踪第4期&#xff0c;指数组合数据截止日2024-12-01&#xff0c;要点如下 近1年A股风格因子检验统…

Linux内存管理:(七)页面回收机制

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 触发页面回收 Linux内核中触发页…

TS 36.213 V12.0.0-PUCCH过程

​本文的内容主要涉及TS 36.213&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

2024 Midjourney 基础教程(⼆):了解 Midjourney Bot 和AI绘画使用技巧进阶教学

在上⼀篇⽂章中&#xff0c;我们学到了如何注册 Midjourney &#xff0c;开通付费订阅&#xff0c;并画出了可能是⾃⼰的第⼀张 AI绘画。怎么样&#xff1f;这种将想象的画⾯&#xff0c;变为现实世界图⽚的感觉。 是否有种造物者的错觉&#xff0c;同时有种开盲盒的惊喜感&…

javaWebssh校园物业管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh校园物业管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用 B/S模式开发。开发环境为TOMCAT7.…