在 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 教程中猫图像的阈值

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

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

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

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

相关文章

机器学习终极指南:统计和统计建模03/3 — 第 -3 部分

系列上文:机器学习终极指南:特征工程(02/2) — 第 -2 部分 一、说明 在终极机器学习指南的第三部分中,我们将了解统计建模的基础知识以及如何在 Python 中实现它们,Python 是一种广泛用于数据分析和科学计…

Spring Security认证架构介绍

在之前的Spring Security:总体架构中,我们讲到Spring Security整个架构是通过Bean容器和Servlet容器对过滤器的支持来实现的。我们将从过滤器出发介绍Spring Security的Servlet类型的认证架构。 1.AbstractAuthenticationProcessingFilter AbstractAut…

Git的介绍和命令汇总

目录 一、git介绍 1、git的工作区域 2、git中文件的四种状态 二、常用命令 1、基础命令 2、提交类命令 3、删除类命令 4、分支类相关命令 5、 查看类相关命令 6、撤销类命令 一、git介绍 1、git的工作区域 在Git中,有四个工作区域:工作区域&am…

CorelDRAW Graphics Suite2024完整版最新功能介绍

CorelDRAW平面设计软件通常也被叫做CDR,CDR广泛应用于排版印刷、矢量图形编辑及网页设计等领域。通过CorelDRAW体验极具个性的自由创作,大胆展现真我,交付出众的创意作品。CorelDRAW拥有矢量插图、页面布局、图片编辑和设计工具,无…

迅为RK3568开发板RTMP推流之视频监控

1 搭建 RTMP 媒流体服务器 nginx-rtmp 是一个基于 nginx 的 RTMP 服务模块,是一个功能强大的流媒体服务器模块, 它提供了丰富的功能和灵活的配置选项,适用于构建各种规模的流媒体平台和应用。无论是搭建实时视频直播平台、点播系统或多屏互…

leetcode 114. 二叉树展开为链表

2023.10.22 本题第一反应就是将 原二叉树的节点值 用先序遍历的方式保存到一个集合数组中。然后再重新构造出新的二叉树。 java代码如下: /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode rig…

我国跨境电商行业研究报告(2022)

我国跨境电商行业研究报告 我国跨境电商规模突飞猛进,2022年进出口规模超2万亿元,2023年上半年跨境电商出口8210亿元,增长19.9%。全国跨境电商主体已超10万家,近年来涌现出一批上市公司,以及广州希音等全球独角兽企业。…

curl命令服务器上执行http请求

1. 现在本地使用postman生成curl命令 注意: 将ip改成127.0.0.1,端口是实际服务运行的端口 curl --location --request POST http://127.0.0.1:63040/content/course/list?pageNo1&pageSize2 \ --header Content-Type: application/json \ --data-raw {"courseName&q…

GO学习之 goroutine的调度原理

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…

JavaSE入门---掌握面向对象三大特性:封装、继承和多态

文章目录 封装什么是封装?如何实现封装? 继承什么是继承?继承的语法父类成员访问子类访问父类的成员变量子类访问父类的成员方法 认识super关键字认识final关键字子类的构造方法super VS this在继承关系中各代码块的执行顺序是怎样的&#xf…

数据可视化与GraphQL:利用Apollo创建仪表盘

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

YOLO目标检测——人脸识别数据集【对应voc、coco和yolo三种格式标签】

实际项目应用:安全监控、智能驾驶、人机交互、人脸门禁、人脸支付、人脸搜索数据集说明:人脸识别数据集,真实场景的高质量图片数据,数据场景丰富,含有人脸图片标签说明:使用lableimg标注软件标注&#xff0…

PHP 基础

PHP 基础 概述 在PHP 文件中&#xff0c;可以与HTML 和JavaScript 混编。 开始标记<?php 表示进入PHP 模式&#xff0c;结束标记?>&#xff0c;标识退出PHP 模式。 PHP 模式之外的内容会被作为字符输出到浏览器中。 PHP 在服务端执行&#xff0c;HTML 和 JS 在浏览…

【iOS】UITableView总结(Cell的复用原理、自定义Cell、UITableViewCell协议方法)

UITableView 列表的特点&#xff1a; 数据量大样式较为统一通常需要分组垂直滚动通常可视区只有一个 -> 视图的复用 UITableViewDataSource UITableView作为视图&#xff0c;只负责展示&#xff0c;协助管理&#xff0c;不管理数据 需要开发者为UITableView提供展示所需…

登上抖音热搜榜:如何让你的内容火爆全网

在当今信息爆炸的时代&#xff0c;抖音已经成为了很多人获取信息、娱乐和社交的重要平台。每一天&#xff0c;都有大量的短视频在抖音上诞生&#xff0c;然而&#xff0c;只有少数幸运儿能够登上抖音热搜榜&#xff0c;成为万人瞩目的焦点。那么&#xff0c;如何让你的内容火爆…

Go并发编程之四

一、前言 今天我们介绍一下Go并发编程另外一个重要概念【多路复用】&#xff0c;多路复用最开始是在网络通讯领域&#xff08;硬件&#xff09;应用&#xff0c;指的是用同一条线路承载多路信号进行通信的方式&#xff0c;有频分多路复用、时分多路复用等等技术&#xff0c;然…

MySQL日志 错误日志 二进制日志 查询日志 慢查询日志

一、错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的&#xff0c;默认存放目录/var/log/,默认的日志文件名…

2019年亚太杯APMCM数学建模大赛A题基于图像分析的二氧化硅熔化表示模型求解全过程文档及程序

2019年亚太杯APMCM数学建模大赛 A题 基于图像分析的二氧化硅熔化表示模型 原题再现 铁尾矿的主要成分是二氧化硅&#xff0c;而二氧化硅是铁尾矿成分中最难熔化的部分。因此&#xff0c;铁尾矿的熔融行为可以用二氧化硅的熔融行为来表示。然而&#xff0c;高温熔池的温度超过…

Jmeter的性能测试

性能测试的概念 定义&#xff1a;软件的性能是软件的一种非功能特性&#xff0c;它关注的不是软件是否能够完成特定的功能&#xff0c;而是在完成该功能时展示出来的及时性。 由定义可知性能关注的是软件的非功能特性&#xff0c;所以一般来说性能测试介入的时机是在功能测试…

Python---练习:while循环嵌套(用两次while三步走--里外各一次)

1、循环嵌套的引入 案例&#xff1a; 有天女朋友又生气了&#xff0c;惩罚&#xff1a;说3遍“老婆大人&#xff0c; 我错了”&#xff0c;这个程序是不是循环即可&#xff1f;但如果女朋友说&#xff1a;还要刷今天晚饭的碗&#xff0c;这个程序怎么书写&#xff1f; 思考&…