当前位置: 首页 > news >正文

在 Python 中使用 Pillow 进行图像处理【2/4】

第二部分

一、说明

        该文是《在 Python 中使用 Pillow 进行图像处理》的第二部分,主要介绍pil库进行一般性处理:如:图像卷积、钝化、锐化、阈值分割。

二、在 Python 中使用 Pillow 进行图像处理

        您已经学习了如何裁剪和旋转图像、调整图像大小以及从彩色图像中提取色带。但是,到目前为止您所采取的所有操作都没有对图像的内容进行任何更改。在本部分中,您将了解 Python Pillow 库中的图像处理功能。您将在 Pillow 中使用该ImageFilter模块。

2.1 使用卷积核的图像过滤器

        图像处理中使用的方法之一是使用内核的图像卷积。本教程的目的不是详细解释图像处理理论。如果您对图像处理科学感兴趣,您可以使用的最佳资源之一是Gonzalez 和 Woods 的《数字图像处理》。

        在本节中,您将学习如何使用卷积核执行图像处理的基础知识。但什么是卷积核呢?核是一个矩阵:

卷积核

        您可以考虑一个简单的图像来理解使用内核进行卷积的过程。该图像具有像素大小30x30并包含一条垂直线和一个点。该线有四个像素宽,点由一个4x4像素正方形组成。出于显示目的,下图已放大:

演示卷积核的图像

        您可以将内核放置在图像上的任何位置,并使用内核中心单元的位置作为参考。下图是图像左上角部分的表示:

核卷积图

        该图中的元素代表图像和内核的不同方面:

  • 白色方块表示图像中值为 的像素0
  • 红色方块表示图像中值为 的像素255。这些构成了上图中的点。
  • 每个紫色区域代表内核。该内核由一个3x3区域组成,内核中的每个单元格的值为1/9。该图显示了标记为 1、2 和 3 的三个不同位置的内核。

图像与内核卷积的结果可以创建新图像。可以通过以下步骤来理解卷积过程:

  1. 定位内核:考虑内核位置之一并查看内核的九个单元覆盖的图像像素。
  2. 乘以内核和像素值:将每个内核单元中的值与图像中相应的像素值相乘。九次乘法将得到九个值。
  3. 乘法结果求和:将这九个值加在一起。结果将是新图像中与内核中心像素具有相同坐标的像素值。
  4. 对所有像素重复:对图像中的每个像素重复该过程,每次移动内核,以便内核的中心单元每次对应不同的图像像素。

        您可以通过上图中标记为 1、2 和 3 的三个内核位置来查看此过程。考虑标记为 1 的内核位置。该内核的位置是(3, 2),这是其中心单元的位置,因为它位于第四行 (index = 3) 和第三列 (index = 2)。内核覆盖区域中的每个图像像素的值都为零。

因此,步骤 2 中的所有乘法都将为零,并且它们的加法也将为零。新图像的像素值为零(3, 2)

        对于所示的其他内核位置,情况有所不同。接下来,考虑标记为 2 的内核,位于(4, 7)。与此重叠的图像像素之一不为零。该像素值与核值相乘将得到255 x (1/9) = 28.33。剩余的八次乘法仍然为零,因为图像像素为零。(4, 7)因此,新图像中位置处的像素值为28.33

        上面所示的第三个内核位置位于(8, 11)。有四个非零图像像素与该内核重叠。每个像素位置的值为255,因此乘法结果将再次28.33针对每个像素位置。该内核位置的总体结果是28.33 x 4 = 113.33。新图像的该值将为(8, 11)

        该图和上面的讨论仅考虑了三个内核位置。卷积过程对图像中每个可能的内核位置重复此过程。这给出了新图像中每个像素位置的值。

        卷积的结果如下图右侧所示,左侧为原始图像:

使用 Python Pillow 的卷积核演示

        您使用的内核是框模糊内核。因子1/9存在,因此内核的总体权重为1。卷积的结果是原始图像的模糊版本。还有其他内核执行不同的功能,包括不同的模糊方法、边缘检测、锐化等。

        Python Pillow 库有几个内置内核和函数,可以执行上述卷积。您无需了解通过卷积进行过滤的数学原理即可使用这些过滤器,但了解使用这些工具时幕后发生的情况总是有帮助的。

        接下来的部分将介绍ImageFilterPillow 模块中可用的内核和图像过滤功能。

2.2 图像模糊、锐化和平滑

您将返回使用在本教程开始时使用的建筑物图像。您可以为此部分启动一个新的 REPL 会话:

>>>

>>> from PIL import Image, ImageFilter
>>> filename = "buildings.jpg"
>>> with Image.open(filename) as img:
...     img.load()
...

除了 之外Image,您还可以ImageFilter从 Pillow 导入该模块。您可以使用该.filter()方法对图像应用过滤。此方法需要一个卷积核作为其参数,您可以使用 Pillow 模块中可用的几个内核之一ImageFilter。您将了解的第一组滤镜用于处理图像的模糊、锐化和平滑。

您可以使用预定义的滤镜模糊图像ImageFilter.BLUR

>>>

>>> blur_img = img.filter(ImageFilter.BLUR)
>>> blur_img.show()

显示的图像是原始图像的模糊版本。您可以使用放大以更详细地观察差异.crop(),然后使用以下命令再次显示图像.show()

>>>

>>> img.crop((300, 300, 500, 500)).show()
>>> blur_img.crop((300, 300, 500, 500)).show()

两张裁剪后的图像显示了两个版本之间的差异:

Python Pillow 中显示模糊的图像

ImageFilter.BoxBlur()您可以使用或自定义所需的模糊类型和数量ImageFilter.GaussianBlur():

>>>

>>> img.filter(ImageFilter.BoxBlur(5)).show()
>>> img.filter(ImageFilter.BoxBlur(20)).show()
>>> img.filter(ImageFilter.GaussianBlur(20)).show()

您可以看到下面的三个模糊图像,其显示顺序与上面代码中的顺序相同:

Python Pillow 中显示模糊的图像

.BoxBlur()滤波器与上一节介绍卷积核时描述的滤波器类似。参数是框模糊滤镜的半径。在前面讨论内核的部分中,您使用的框模糊滤镜是一个3x3滤镜。这意味着它的半径为1,因为滤镜从中心延伸了一个像素。

模糊图像显示,半径为 的框模糊滤镜20生成的图像比半径为 的框模糊滤镜生成的图像更模糊5

您还可以使用.GaussianBlur()过滤器,它使用高斯模糊内核。高斯核对核中心像素的权重比边缘像素的权重更大,这会导致比框模糊获得的模糊更平滑。因此,高斯模糊在很多情况下可以给出更好的结果。

如果你想锐化图像怎么办?在这种情况下,您可以使用ImageFilter.SHARPEN过滤器并将结果与​​原始图像进行比较:

>>>

>>> sharp_img = img.filter(ImageFilter.SHARPEN)
>>> img.crop((300, 300, 500, 500)).show()
>>> sharp_img.crop((300, 300, 500, 500)).show()

您正在比较两个图像的裁剪版本,显示建筑物的一小部分。锐化后的图像如右图所示:

显示 Python Pillow 中锐化的图像

也许您需要平滑图像,而不是锐化图像。ImageFilter.SMOOTH您可以通过作为参数传递来实现此目的.filter()

>>>

>>> smooth_img = img.filter(ImageFilter.SMOOTH)
>>> img.crop((300, 300, 500, 500)).show()
>>> smooth_img.crop((300, 300, 500, 500)).show()

下面,您可以看到左侧为原始图像,右侧为平滑后的图像:

显示 Python Pillow 中锐化的图像

        您将在下一节中看到平滑过滤器的应用,其中您将了解模块中的更多过滤器ImageFilter。这些滤镜作用于图像中对象的边缘。

2.3 边缘检测、边缘增强和压花

        当您查看图像时,确定该图像中对象的边缘相对容易。算法也可以使用边缘检测内核自动检测边缘。

        Pillow 中的模块ImageFilter有一个预定义的内核来实现此目的。在本部分中,您将再次使用建筑物图像并将其转换为灰度,然后再应用边缘检测滤镜。您可以继续上一节中的 REPL 会话:

>>> img_gray = img.convert("L")
>>> edges = img_gray.filter(ImageFilter.FIND_EDGES)
>>> edges.show()

结果是显示原始图像边缘的图像:

Python Pillow 中的边缘检测

该过滤器识别图像中的边缘。ImageFilter.SMOOTH在查找边缘之前应用过滤器可以获得更好的结果:

>>>

>>> img_gray_smooth = img_gray.filter(ImageFilter.SMOOTH)
>>> edges_smooth = img_gray_smooth.filter(ImageFilter.FIND_EDGES)
>>> edges_smooth.show()

您可以在下面看到原始灰度图像和两个边缘检测结果的比较。边缘检测之前进行平滑的版本显示在底部:

Python Pillow 中的边缘检测

您还可以使用滤镜增强原始图像的边缘ImageFilter.EDGE_ENHANCE

>>>

>>> edge_enhance = img_gray_smooth.filter(ImageFilter.EDGE_ENHANCE)
>>> edge_enhance.show()

您使用灰度图像的平滑版本来增强边缘。下面并排显示了原始灰度图像的一部分和边缘增强的图像。右侧是经过边缘增强的图像:

Python Pillow 中的边缘增强

另一个ImageFilter处理对象边缘的预定义过滤器是ImageFilter.EMBOSS。您可以将其作为参数传递给.filter()本节中的其他过滤器:

>>>

>>> emboss = img_gray_smooth.filter(ImageFilter.EMBOSS)
>>> emboss.show()

您使用平滑的灰度版本作为此过滤器的起点。您可以看到下面的浮雕图像,它使用图像中的边缘显示了不同的效果:

Python Pillow 中的图像浮雕

在本节中,您了解了ImageFilter模块中可应用于图像的几个可用过滤器。您还可以使用其他过滤器来处理图像。ImageFilter您可以在文档中查看所有可用过滤器的列表。

三、图像分割和叠加

3.1 先给出一个例子

   cat.jpg在本部分中,您将使用名为( imagecredit ) 和monastery.jpg( imagecredit )的图像文件,您可以在本教程的图像存储库中找到这些文件:

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

        这是两张图片:

Python Pillow 教程中使用的猫图像

用于 Python Pillow 教程的修道院庭院图像

        您可以使用 Python Pillow 库从第一张图像中提取猫并将其放置在修道院庭院的地板上。您将使用多种图像处理技术来实现此目的。

3.2 图像阈值处理

        您将从工作开始cat.jpg。您需要使用图像分割技术从背景中删除猫的图片。在此示例中,您将使用阈值技术分割图像。

        首先,您可以将图像裁剪为较小的图像以删除一些背景。您可以为此项目启动一个新的 REPL 会话:

>>> from PIL import Image
>>> filename_cat = "cat.jpg">>> with Image.open(filename_cat) as img_cat:
...     img_cat.load()
...>>> img_cat = img_cat.crop((800, 0, 1650, 1281))
>>> img_cat.show()

        裁剪后的图像包含猫和一些距离猫太近而无法裁剪的背景:

裁剪后的猫图像

        彩色图像中的每个像素都由与该像素的红色、绿色和蓝色值相对应的三个数字来数字表示。阈值处理是将所有像素转换为最大值或最小值的过程,具体取决于它们是否高于或低于某个数字。在灰度图像上执行此操作更容易:

>>> img_cat_gray = img_cat.convert("L")
>>> img_cat_gray.show()
>>> threshold = 100
>>> img_cat_threshold = img_cat_gray.point(
...     lambda x: 255 if x > threshold else 0
... )
>>> img_cat_threshold.show()

        您可以通过调用将.point()灰度图像中的每个像素转换为 或 来255实现阈值化0。转换取决于灰度图像中的值是大于还是小于阈值。本例中的阈值是100

        下图显示了灰度图像和阈值处理的结果:

Python Pillow 中的阈值

        在此示例中,灰度图像中像素值大于 的所有点都100转换为白色,所有其他像素都更改为黑色。您可以通过改变阈值来更改阈值处理的灵敏度。

        当要分割的对象与背景不同时,可以使用阈值来分割图像。您可以使用具有更高对比度的原始图像版本获得更好的结果。在此示例中,您可以通过对原始图像的蓝色通道而不是灰度图像进行阈值化来实现更高的对比度,因为背景中的主色是棕色和绿色,其中蓝色成分较弱。

        您可以像之前一样从彩色图像中提取红色、绿色和蓝色通道:

>>> red, green, blue = img_cat.split()
>>> red.show()
>>> green.show()
>>> blue.show()

        下面从左到右显示了红色、绿色和蓝色通道。所有三个都显示为灰度图像:

猫图像的颜色通道

蓝色通道在代表猫的像素和代表背景的像素之间具有更高的对比度。您可以使用蓝色通道图像来阈值:

>>> threshold = 57
>>> img_cat_threshold = blue.point(lambda x: 255 if x > threshold else 0)
>>> img_cat_threshold = img_cat_threshold.convert("1")
>>> img_cat_threshold.show()

  在此示例中,您使用阈值57"1"您还可以使用 的参数将图像转换为二进制模式.convert()。二值图像中的像素只能具有0或的值1

        注意:处理某些依赖有损压缩的图像格式(例如 JPEG)时,图像可能会略有不同,具体取决于您使用的 JPEG 解码器。不同的操作系统通常具有不同的默认 JPEG 解码器。因此,处理图像时获得的结果可能会有所不同,具体取决于您使用的操作系统和 JPEG 解码器。

        如果您的结果与本教程中显示的结果不匹配,您可能需要稍微调整阈值。

        阈值化的结果如下:

改进了 Python Pillow 教程中猫图像的阈值

        您可以在这张黑白图像中识别出这只猫。但是,您希望图像中与猫对应的所有像素都是白色,而所有其他像素都是黑色。在此图像中,与猫相对应的区域仍然有黑色区域,例如眼睛、鼻子和嘴巴所在的位置,并且图像中的其他位置仍然有白色像素。

您可以使用称为腐蚀和膨胀的图像处理技术来创建更好的代表猫的蒙版。您将在下一节中了解这两种技术。

相关文章:

在 Python 中使用 Pillow 进行图像处理【2/4】

第二部分 一、说明 该文是《在 Python 中使用 Pillow 进行图像处理》的第二部分,主要介绍pil库进行一般性处理:如:图像卷积、钝化、锐化、阈值分割。 二、在 Python 中使用 Pillow 进行图像处理 您已经学习了如何裁剪和旋转图像、调整图像大…...

XTU-OJ 1171-coins

题目描述 一个均质硬币抛n次,求不存在连续2次为正面的方案数。 输入 每行一个正整数n,n≤40。如果n为0,表示输入结束,不需要处理。 输出 每行输出一个结果,为一个整数。 样例输入 1 2 3 0样例输出 2 3 5 解题思路&…...

如何使用 JMeter 进行 HTTPS 请求测试?

本文将介绍如何使用 JMeter 测试 HTTPS 请求,并提供相关的技巧和注意事项。 在进行性能测试时,很多网站都采用了 HTTPS 协议。当我们测试 HTTPS 请求,如果服务端开启了双向认证,则需要客户端发送请求时带上证书。本文介绍如何在 …...

KNN-水仙花的分类

题目: 思路: 1、处理数据集,这里用的是题目已知的数据集,所以说需要提前将写好的数据放到excel表格里,再进行读取。 2、将数据集划分为训练集和测试集 3、定义K-NN模型。 4、训练模型 5、预测模型 6、计算分类精…...

Kotlin 如何确定协程是否启动

在Kotlin中,你可以确定协程是否已启动并正在运行,可以使用Job接口来管理协程,并使用一些函数来检查协程的状态。以下是一些常见的方法: 1.launch 函数返回一个 Job 对象,可以使用这个对象来确定协程的状态。例如&…...

【Spring Boot】Spring Boot集成RabbitMQ

一、发送和接收消息 Spring Boot提供了`spring-boot-starter-amqp`组件,只需要简单地配置即可与Spring Boot无缝集成。下面通过示例演示集成RabbitMQ实现消息的接收和发送。 步骤01 配置pom包。 创建Spring Boot项目并在pom.xml文件中添加spring-bootstarter-amqp等相关组件…...

Hadoop部署过程中问题总结

Hadoop伪分布式集群部署问题总结 一、HDFS初始化失败 初始化失败,HDFS初始化操作如下: hdfs namenode -format然后我运行后报错:error parsing conf core-site.xml 出现这个信息就说明core-site.xml配置文件出错了,用vim命令可…...

低成本IC上岸攻略—IC设计网课白嫖篇

数字电路基础 清华大学 王红主讲:数字电子技术基础 西安电子科技大学 任爱锋主讲:数字电路与逻辑设计 模拟电路基础 上交大 郑益慧主讲:模拟电子技术基础 清华大学 华成英主讲:模拟电子技术基础 半导体物理: 西…...

BootLoader为什么要分阶段?

BootLoader(引导加载程序)分阶段的设计主要是为了实现系统的启动和引导过程的可靠性、可维护性和灵活性。这种分阶段的设计允许引导加载程序执行不同的任务,并在不同的环境下工作。以下是引导加载程序分阶段的主要原因: 1. 启动环…...

Centos8: 安装python2, 并设置默认版本

文章目录 原本centos上已经有python3.6了,因为要运行旧代码,需要安装python2版本。 #在CentOS 8上安装Python 2 sudo dnf install python2#设置默认Python版本 python2 sudo alternatives --set python /usr/bin/python2#设置默认Python版本 python3 sud…...

【逆向】导入表注入

练手的exe链接 链接:https://pan.baidu.com/s/1_87QNHaZYlfY_5uwIRePUQ?pwd6gds 提取码:6gds 原理: 在动态链接库一章提到DllMain,这里再回顾一次 当dll被加载进4GB空间时,会调用一次DllMain(入口方法&…...

Unity游戏开发中打造游戏攻击技能架构与设计

一、技能系统的设计 在 MOBA 游戏中,每个英雄角色都会有多个技能,这些技能可以分为普通攻击和技能攻击两种。普通攻击是英雄角色的基本攻击方式,而技能攻击则需要消耗一定的资源(如蓝量)才能使用。在设计技能系统时&a…...

【微信小程序开发】小程序微信用户授权登录(用户信息手机号)

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 授权流程讲解 一.用户信息授权登录 1.w…...

VSCode 自动格式化

1.打开应用商店,搜索 prettier code formatter ,选择第一个,点击安装。 2.安装完成后,点击文件,选择首选项,选择设置。 3.在搜索框内输入 save ,勾选在保存时格式化文件。 4.随便打开一个文件&a…...

数据库、数据仓库相关

1. 数据库与数据仓库的区别 数据库 Database (Oracle, Mysql, PostgreSQL)主要用于事务处理。数据仓库 Datawarehouse (Amazon Redshift, Hive)主要用于数据分析。 数据库和数据仓库是两种不同的数据存储方式,它们的设计目的和使用场景也有所不同。数据库通常用于…...

【STM32】RCC时钟模块(使用HAL库)

https://gitee.com/linhir-linhir/stm32-f103-c8/blob/master/STM32%E6%9C%80%E6%96%B0%E5%9B%BA%E4%BB%B6%E5%BA%93v3.5/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h STM32最新固件库v3.5/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c…...

WPF中的绑定知识详解(含案例源码分享)

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

【JVM】类的生命周期

【JVM】类的生命周期 文章目录 【JVM】类的生命周期1. 生命周期概述2. 加载阶段3. 连接阶段3.1 验证3.2 准备3.3 解析 4. 初始化阶段4.1 触发初始化的方式4.2 clinit不存在的情况4.3 多个类的初始化 5. 总结 1. 生命周期概述 类的生命周期分为5/7个阶段: 加载(Loa…...

asp.net网上商城系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio协同过滤设计

一、源码特点 asp.net网上商城系统是一套完善的web设计管理系统系统采用协同过滤算法进行商品推荐,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库 为sqlserver2008,使用c#语言开发 ASP…...

APUS入驻百度灵境矩阵,普惠AI大模型插件能力

10月17日,APUS出席百度世界大会2023。会上,百度公布了灵境矩阵业务进展,APUS作为灵境矩阵首批合作伙伴正与百度携手拓展大模型能力边界、构建大模型应用生态。 百度认为,大模型将繁荣AI应用生态,在生态搭建过程中&…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...

前端调试HTTP状态码

1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...