【Pillow库的内涵】01/3 进行基本图像操作

一、说明

        Pillow 具有被 Python 社区广泛使用的优势,并且它不像其他一些图像处理库那样具有陡峭的学习曲线。应用PIL库的Image对象,益处很多,首先它可以处理网上URL文件,其次,图片可以方面转化成int32、64或float类型,因而可以方便实现变换和显示uint8。尤其和Tkinter搭配,用起来非常方便顺手。

二、内容提要

  • 使用 Python Pillow 库进行基本图像操作
  • Pillow 中的图像模块和图像类
  • 基本图像处理
  • Python Pillow 库中图像的波段和模式
  • 在 Python 中使用 Pillow 进行图像处理
  • 使用卷积核的图像过滤器
  • 图像模糊、锐化和平滑
  • 边缘检测、边缘增强和压花
  • 图像分割和叠加:一个例子
  • 图像阈值处理
  • 腐蚀和膨胀
  • 使用阈值分割图像
  • 使用 Image.paste() 叠加图像
  • 创建水印
  • 使用 NumPy 和 Pillow 进行图像处理
  • 使用 NumPy 相互减去图像
  • 使用 NumPy 创建图像
  • 创建动画
  • 结论

三、使用 Python Pillow 库进行基本图像操作

        Python Pillow 库是一个名为 PIL 的旧库的分支。PIL 代表 Python Imaging Library,它是使 Python 能够处理图像的原始库。PIL 于 2011 年停产,仅支持 Python 2。按照开发人员自己的描述,Pillow 是友好的 PIL 分支,它使库保持活力并包含对 Python 3 的支持。

        Python 中有不止一个模块来处理图像并执行图像处理。如果您想通过操作像素直接处理图像,那么您可以使用NumPy和SciPy。其他流行的图像处理库是OpenCV、scikit-image和Mahotas。其中一些库比 Pillow 更快、更强大。

        然而,Pillow 仍然是处理图像的重要工具。它提供的图像处理功能类似于 Photoshop 等图像处理软件中的功能。Pillow 通常是不需要更高级图像处理专业知识的高级图像处理任务的首选。它也经常用于处理图像时的探索性工作。      

        您需要先安装该库才能使用它。您可以pip在虚拟环境中使用以下命令安装 Pillow :

  • 视窗
  • Linux + macOS
PS> python -m venv venv
PS> .\venv\Scripts\activate
(venv) PS> python -m pip install Pillow

        现在您已经安装了该软件包,您可以开始熟悉Python Pillow 库并执行基本的图像操作。

3.1 Pillow 中的模块ImageImage

        Pillow 中定义的主要类是Image类。当您使用 Pillow 读取图像时,图像将存储在 类型的对象中Image

        对于本部分中的代码,您将需要名为buildings.jpg( imagecredit ) 的图像文件,您可以在本教程的图像存储库中找到该文件:

        获取图像: 单击此处访问您将使用 Pillow 操作和处理的图像。

        您可以将此图像文件放置在您正在使用的项目文件夹中。

        使用 Pillow 探索图像时,最好使用交互式 REPL 环境。首先打开刚刚下载的图像:

>>>

>>> from PIL import Image
>>> filename = "buildings.jpg"
>>> with Image.open(filename) as img:
...     img.load()
...>>> type(img)
<class 'PIL.JpegImagePlugin.JpegImageFile'>>>> isinstance(img, Image.Image)
True

        您可能希望从 Pillow 导入,而不是从 PIL 导入。Pillow毕竟你确实安装了,而不是PIL。然而,Pillow 是 PIL 库的一个分支。PIL因此,在导入代码时您仍然需要使用。

        您调用该open()函数从文件中读取图像并将.load()图像读入内存,以便现在可以关闭文件。您可以使用with语句创建上下文管理器,以确保文件在不再需要时立即关闭。

        在此示例中,对象是 JPEG 图像特定类型,它是该类的子类Image,正如您通过调用 来确认的那样isinstance()。请注意,类和定义该类的模块共享相同的名称Image。您可以使用以下命令显示图像.show():

>>>

>>> img.show()

.show()方法将图像保存为临时文件,并使用操作系统的本机软件处理图像来显示它。当您运行上面的代码时,您将看到显示以下图像:

Python Pillow 教程中使用的建筑物图像

        在某些系统上,调用.show()将阻止 REPL,直到您关闭映像。这取决于操作系统和您使用的默认图像查看软件。

        在处理 Python Pillow 库中的图像时,您需要熟悉三个关键属性。您可以使用Image类属性.format、.size和来探索这些.mode:

>>>

>>> img.format
'JPEG'>>> img.size
(1920, 1273)>>> img.mode
'RGB'

        图像的格式显示了您正在处理的图像类型。在本例中,图像的格式为'JPEG'. 尺寸显示图像的宽度和高度(以像素为单位)。该图像的模式是'RGB'. 您很快就会了解有关模式的更多信息。

        通常,您可能需要裁剪图像并调整图像大小。该类有两个Image方法可用于执行这些操作.crop():.resize()

>>>

>>> cropped_img = img.crop((300, 150, 700, 1000))
>>> cropped_img.size
(400, 850)>>> cropped_img.show()>>> low_res_img = cropped_img.resize(
...     (cropped_img.width // 4, cropped_img.height // 4)
... )
>>> low_res_img.show()

        的参数.crop()必须是一个 4 元组,用于定义要裁剪的区域的左边缘、上边缘、右边缘和下边缘。Pillow 中使用的坐标系将坐标 (0, 0) 分配给左上角的像素。这与通常用于二维数组的坐标系相同。4 元组代表图像的以下部分:

裁剪操作显示从原点获取的尺寸

.crop()上面代码中返回的新图像的大小为400x850像素。裁剪后的图像仅显示原始图片中的一栋建筑物:

Python Pillow 教程中的裁剪图像

        在上面的代码中,您还可以使用 更改裁剪图像的分辨率.resize(),这需要一个元组作为必需参数。用作参数的元组定义图像的新宽度和高度(以像素为单位)。

        在上面的示例中,您使用楼层除法运算符( //) 以及Image属性.width和,将新的宽度和高度设置为其原始值的四分之一.height。最后调用show()显示裁剪和调整大小的图像:

在 Python Pillow 教程中调整图像大小

        您可以使用其他可选参数来.resize()控制图像的重新采样方式。或者,您可以使用以下方法实现类似的缩放.reduce():

>>>

>>> low_res_img = cropped_img.reduce(4)

        该参数决定了缩小图像的因子。如果您更喜欢设置最大尺寸而不是缩放因子,那么您可以使用.thumbnail()。缩略图的大小将小于或等于您设置的大小。

        注意:.thumbnail()方法会Image就地更改对象,并且不会返回新对象。但是,.crop().resize().reduce()都返回一个新Image对象。并非 Pillow 库中的所有方法都具有相同的行为方式。

Image一旦您对返回的图像感到满意,您可以使用以下命令将任何对象保存到文件中.save():

>>>

>>> cropped_img.save("cropped_image.jpg")
>>> low_res_img.save("low_resolution_cropped_image.png")

        调用该方法后,它会在项目文件夹中创建图像文件。在此示例中,其中一个图像是 JPEG 图像,另一个是 PNG 图像。用作文件名的扩展名会自动确定文件格式,或者您可以将格式指定为附加可选参数。

3.2 基本图像处理

        除了裁剪和调整大小之外,您还可以对图像进行操作。另一个常见的要求是旋转或翻转图像。您可以使用该.transpose()方法进行一些转换。继续执行您在上一节中开始的相同 REPL 会话:

>>>

>>> converted_img = img.transpose(Image.FLIP_TOP_BOTTOM)
>>> converted_img.show()

        此代码显示以下图像:

Python Pillow 教程中的翻转图像

        您可以将七个选项作为参数传递给.transpose()

  1. Image.FLIP_LEFT_RIGHT将图像从左向右翻转,形成镜像
  2. Image.FLIP_TOP_BOTTOM将图像从上到下翻转
  3. Image.ROTATE_90将图像逆时针旋转 90 度
  4. Image.ROTATE_180将图像旋转 180 度
  5. Image.ROTATE_270将图像逆时针旋转 270 度,与顺时针旋转 90 度相同
  6. Image.TRANSPOSE以左上角像素为原点转置行和列,转置图像中的左上角像素与原始图像中的相同
  7. Image.TRANSVERSE使用左下像素作为原点转置行和列,左下像素是原始版本和修改版本之间保持固定的像素

        上面的所有旋转选项都以 90 度为步长定义旋转。如果您需要将图像旋转另一个角度,那么您可以使用.rotate():

>>>

>>> rotated_img = img.rotate(45)
>>> rotated_img.show()

        此方法调用将图像逆时针旋转 45 度,得到以下图像:

Python Pillow 教程中的旋转图像

        返回的对象Image与原始对象大小相同Image。因此,该显示中缺少图像的角点。您可以使用命名参数更改此行为expand

>>>

>>> rotated_img = img.rotate(45, expand=True)
>>> rotated_img.show()

        此方法返回完全包含旋转图像的更大图像:

Python Pillow 教程中带有展开参数的旋转图像

您可以使用其他可选参数进一步自定义旋转。您现在可以更改图像的大小和方向。在下一节中,您将了解 Python Pillow 库中不同类型的图像。

3.3 Python Pillow 库中图像的波段和模式

        图像是像素的二维阵列,其中每个像素对应一种颜色。每个像素可以由一个或多个值表示。例如,在RGB图像中,每个像素由与该像素的红色、绿色和蓝色值相对应的三个值表示。

        因此,ImageRBG 图像的对象包含三个波段,每个波段对应一种颜色。像素大小的 RGB 图像由值数组100x100表示。100x100x3

        RGBA图像还包括 alpha 值,其中包含有关每个像素透明度的信息。RGBA 图像有四个色带,一个色带代表每种颜色,第四个色带包含 Alpha 值。每个带具有与图像尺寸相同的尺寸。因此,尺寸为像素的 RGBA 图像由值数组100x100表示。100x100x4

        图像的模式描述了您正在使用的图像类型。Pillow 支持大多数标准模式,包括黑白(二进制)、灰度、RGB、RGBA 和CMYK。您可以在有关模式的 Pillow 文档中查看支持的模式的完整列表。

   Image您可以使用该方法找出对象中有多少个带.getbands(),并且可以使用在模式之间进行转换.convert()。现在,您将在本教程中使用图像存储库中名为strawberry.jpg( image Credit )的图像:

Python Pillow 教程的草莓图像

        该图像的模式也是 RGB。您可以将此图像转换为其他模式。此代码使用您在前面部分中启动的相同 REPL 会话:

>>>

>>> filename = "strawberry.jpg"
>>> with Image.open(filename) as img:
...     img.load()
...>>> cmyk_img = img.convert("CMYK")
>>> gray_img = img.convert("L")  # Grayscale>>> cmyk_img.show()
>>> gray_img.show()>>> img.getbands()
('R', 'G', 'B')
>>> cmyk_img.getbands()
('C', 'M', 'Y', 'K')
>>> gray_img.getbands()
('L',)

        您调用.convert()两次将 RGB 图像转换为 CMYK 和灰度版本。CMYK 图像看起来与原始图像相似,但使用印刷材料而不是数字显示的常见模式进行编码。转换为灰度给出以下输出:

        调用的输出.getbands()确认 RGB 图像中有 3 个波段、CMYK 图像中有 4 个波段、灰度图像中有 1 个波段。

        您可以使用 将图像分成多个波段.split(),并Image使用 将单独的波段重新组合回对象中merge()。当您使用 时.split(),该方法将所有带区作为单独的Image对象返回。您可以通过显示返回的对象之一的字符串表示形式来确认这一点:

>>>

>>> red, green, blue = img.split()
>>> red
<PIL.Image.Image image mode=L size=1920x1281 at 0x7FDD80C9AFA0>
>>> red.mode
'L'

        返回对象的模式.split()为,表示这是一张灰度图像,或者是只显示每个像素的亮度'L'值的图像。

   merge()现在,您可以使用模块中的函数创建三个新的 RGB 图像,分别显示红色、绿色和蓝色通道Image

>>>

>>> zeroed_band = red.point(lambda _: 0)>>> red_merge = Image.merge(
...     "RGB", (red, zeroed_band, zeroed_band)
... )>>> green_merge = Image.merge(
...     "RGB", (zeroed_band, green, zeroed_band)
... )>>> blue_merge = Image.merge(
...     "RGB", (zeroed_band, zeroed_band, blue)
... )>>> red_merge.show()
>>> green_merge.show()
>>> blue_merge.show()

        第一个参数merge()确定您要创建的图像的模式。第二个参数包含要合并到单个图像中的各个波段。

        单独存储在变量 中的红色波段red是模式为 L 的灰度图像。要创建仅显示红色通道的图像,请将原始图像中的红色波段与仅包含零的绿色和蓝色波段合并。要创建一个到处都包含零的带,可以使用该.point()方法。

        该方法需要一个函数作为参数。您使用的函数决定每个点的变换方式。在本例中,您使用lambda函数将每个点映射到0

        当您将红色波段与包含零的绿色和蓝色波段合并时,您会得到一个名为 的 RGB 图像red_merge。因此,您创建的 RGB 图像仅在红色通道中具有非零值,但由于它仍然是 RGB 图像,因此它将以彩色显示。

        您还可以重复类似的过程来获取green_mergeblue_merge,其中包含带有来自原始图像的绿色和蓝色通道的 RGB 图像。该代码显示以下三张图像:

Python Pillow 教程的草莓图像单独通道

        红色图像在代表草莓的像素中包含强信号,因为这些像素大部分是红色的。绿色和蓝色通道将这些像素显示为黑色,因为它们的值较小。例外的是那些代表草莓表面上的光反射的像素,因为这些像素几乎是白色的。

        创建本教程中所示的并排显示显示隐藏.

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

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

相关文章

自然语言处理---huggingface平台使用指南

1 huggingface介绍 Huggingface总部位于纽约&#xff0c;是一家专注于自然语言处理、人工智能和分布式系统的创业公司。他们所提供的聊天机器人技术一直颇受欢迎&#xff0c;但更出名的是他们在NLP开源社区上的贡献。Huggingface一直致力于自然语言处理NLP技术的平民化(democr…

设计模式:组合模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介&#xff1a; 组合模式&#xff0c;它是一种用于处理树形结构、表示“部分-整体”层次结构的设计模式。它允许你将对象组合成树形结构&#xff0c;以表示部分和整体的关系。这种模式的主要目的是简化客户端代码&#xff0c;并使客户端以一致的方式处理单个对象和组合对象。…

Flyway Desktop updated

Flyway Desktop updated 为比较工件序列化和反序列化添加了额外的调试日志记录。 Flyway Desktop现在将记住以前用于创建项目和匹配克隆的位置。 新的脱机许可工作流现在已在Microsoft Windows上启用。 现在&#xff0c;在配置目标数据库列表时&#xff0c;环境ID是可见的。 现…

【虹科干货】Redis Enterprise vs ElastiCache——如何选择缓存解决方案?

使用Redis 或 Amazon ElastiCache 来作为缓存加速已经是业界主流的解决方案&#xff0c;二者各有什么优势&#xff1f;又有哪些区别呢&#xff1f; 文况速览&#xff1a; - Redis 是什么&#xff1f; - Redis Enterprise 是什么&#xff1f; - Amazon ElastiCache 是什么&…

tomcat动静分离

1.七层代理动静分离 nginx代理服务器&#xff1a;192.168.233.61 代理又是静态 tomcat1:192.168.233.71 tomcat2:192.168.233.72 全部关闭防火墙 在http模块里面 tomcat1&#xff0c;2 删除上面的hostname 148 配置 直接访问 http://192.168.66.17/index.jsp 2.四层七层动…

常见面试题-Redis专栏(二)

theme: cyanosis typora-copy-images-to: imgsRedisson 分布式锁&#xff1f;在项目中哪里使用&#xff1f;多久会进行释放&#xff1f;如何加强一个分布式锁&#xff1f; 答&#xff1a; 首先入门级别的分布式锁是通过 setnx 进行实现&#xff0c;使用 setnx 实现有四个注意…

中文编程开发语言工具应用案例:ps5体验馆计时收费管理系统软件

中文编程开发语言工具应用案例&#xff1a;ps5体验馆计时收费管理系统软件 软件部分功能&#xff1a; 1、计时计费功能&#xff1a;只需点开始计时即可&#xff0c;时间直观显示 2、商品管理功能&#xff1a;可以管理饮料等商品 3、会员管理功能&#xff1a;支持只用手机号作…

Arcgis 数据操作

在进行数据操作的时候&#xff0c;需要注意坐标系要一致&#xff0c;这是前提。 数据类型 文件地理数据库&#xff1a;gbd 个人地理数据库&#xff1a;mdb &#xff08;Mircosoft Access&#xff09; 矢量数据&#xff1a;shp 推荐使用gbd数据&#xff0c;效率会更高。 采…

【912.排序数组】

目录 一、题目描述二、算法原理2.1快速排序2.2归并排序 三、代码实现3.1快排代码实现3.2归并代码实现 一、题目描述 二、算法原理 2.1快速排序 2.2归并排序 三、代码实现 3.1快排代码实现 class Solution { public:int getRandom(int left,int right,vector<int>&…

[翻译]理解Postgres的IOPS:为什么数据即使都在内存,IOPS也非常重要

理解Postgres的IOPS&#xff1a;为什么数据即使都在内存&#xff0c;IOPS也非常重要 磁盘IOPS&#xff08;每秒输入/输出操作数&#xff09;是衡量磁盘系统性能的关键指标。代表每秒可以执行的读写操作数量。对于严重依赖于磁盘访问的PG来说&#xff0c;了解和优化磁盘IOPS对实…

Ubuntu系统下使用docker容器配置nginx并部署前端项目

1.下载 Nginx 镜像 命令 描述 docker pull nginx 下载最新版 Nginx 镜像 :2. 创建要挂载的宿主机目录 启动前需要先创建 Nginx 外部挂载的配置文件&#xff08; /home/nginx/conf/nginx.conf&#xff09; 之所以要先创建 , 是因为 Nginx 本身容器只存在 / etc/nginx 目录 ,…

iOS 13以下系统,使用iOS QQ 登录 SDK 崩溃问题

最近用iPhone 6p 系统&#xff1a;12.5.4 调用QQ三方登录&#xff0c;出现崩溃到初始化QQ SDK的位置 在询问了QQ官方客服后&#xff0c;得到了答复&#xff0c;可以放弃治疗了

2.IDEA的安装使用指南

学习Java的第二步应该是从IDEA下手&#xff0c;这篇博文介绍了它的安装及使用&#xff0c;希望大家看完后可以独立安装 ~ 文章目录 一、下载安装包二、安装 IDEA三、IDEA 初步上手 一、下载安装包 安装包可以从官网下载&#xff0c;也可以直接私信我拿取。这里主要介绍如何在官…

Swingbench 压力测试(超详细)

目录 前提需要有配置好的oracle哦 1、环境准备 2、安装Swingbench 3、造数据 4、压测 前提需要有配置好的oracle哦 1、环境准备 启动监听 lsnrctl start 启动数据库 sqlplus / as sysdba startup 创建表 CREATE TABLESPACE soe DATAFILE /u01/app/oracle/oradata/or…

2.卷积神经网络(CNN)

一句话引入&#xff1a; 如果我们要做图像识别&#xff0c;用的是一个200x200的图片&#xff0c;那么BP神经网络的输入层就需要40000个神经元&#xff0c;因为是全连接&#xff0c;所以整个BP神经网络的参数量就是160亿个&#xff0c;显然不能这样来训练网络&#xff0c;所以我…

【java】【重构一】分模块开发设计实战

目录 一、创建项目 1、先创建一个空项目 2、设置项目SDK等 二、创建父模块 选择springboot 1、创建父模块parent 2、删除多余文件&#xff0c;只保留pom.xml 3、修改pom.xml 4、将部分公共依赖加入到pom 三、创建实体类子模块entity 1、创建实体类子模块entity 2、…

Jprofiler V14中文使用文档

JProfiler介绍 什么是JProfiler? JProfiler是一个用于分析运行JVM内部情况的专业工具。 在开发中你可以使用它,用于质量保证,也可以解决你的生产系统遇到的问题。 JProfiler处理四个主要问题: 方法调用 这通常被称为"CPU分析"。方法调用可以通过不同的方式进行测…

C++中的继承(超详细)

C中的继承 1.继承的概念及定义1.1继承的概念1.2 继承定义1.2.1 定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换3.继承中的作用域4.派生类的默认成员函数5.继承与友元6.继承与静态成员7.继承的总结和反思 1.继承的概念及定义 1…

新兴网络安全威胁:数字防御新格局

根据Check Point Research (CPR)的数据&#xff0c;今年上半年犯罪活动大幅增加&#xff0c;第二季度全球每周网络攻击激增 8%&#xff0c;这创下了两年来的最高成交量。 勒索软件和黑客行为等传统威胁已经演变&#xff0c;犯罪团伙不断调整其方法和工具来渗透和影响世界各地的…

c语言练习93:环形链表的约瑟夫问题

环形链表的约瑟夫问题 环形链表的约瑟夫问题_牛客题霸_牛客网 描述 编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数&#xff0c;报到 m 的人离开。 下一个人继续从 1 开始报数。 n-1 轮结束以后&#xff0c;只剩下一个人&#xff0c;问最后留下的这个人编号是…