python计算机视觉学习笔记——PIL库的用法

news/2024/11/18 15:31:12/文章来源:https://www.cnblogs.com/wj-1314/p/11044345.html

如果需要处理的原图及代码,请移步小编的GitHub地址

  传送门:请点击我

  如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice

  这个是之前的笔记,自己看到了就顺带发出来,也是温习一下,内容可能不太全,算是入门贴吧。

前言:PIL

   图像处理是计算机视觉领域中不可或缺的一部分,而PIL(Python Imaging Library)库和OpenCV(Open Source Computer Vision Library)是两个常用的工具。今天这里主要学习以下PIL库,PIL 是一个用于图像处理的 Python 库,提供了丰富的图像处理功能。它包含了处理图像的各种工具和算法,可以进行图像的打开、保存、剪裁、旋转、缩放等操作。

  PIL(Python Imaging Library)和 OpenCV 都是用于图像处理的强大库,它们各自有着不同的优势和适用场景。以下是一些导致 PIL 仍然被使用的原因:

1,PIL的优点

  1. 易用性:PIL库的API设计得非常简洁明了,即使是编程新手也能快速上手。例如,你只需要一行代码就可以打开一个图像文件,然后再用一行代码就可以将图像保存到新的文件中。
  2. 功能强大:PIL库提供了丰富的图像处理功能,包括基本的图像操作(如裁剪、旋转、缩放等),图像滤镜,以及更高级的功能(如图像增强、色彩空间转换等)。
  3. 支持多种图像格式:PIL库支持多种常见的图像格式,包括JPEG、PNG、BMP、GIF、PPM、TIFF等。这意味着你可以使用PIL库来处理几乎所有类型的图像文件。
  4. 文字和绘图功能:PIL允许在图像上添加文字、绘制几何图形和绘制曲线,这对于图像注释和标记非常有帮助。
  5. 扩展功能:PIL还支持各种扩展功能,如图像滤波、直方图均衡化和颜色空间转换等。

 

2,PIL 的缺点

  1. 性能:虽然PIL库的功能强大,但是它的性能并不是最优的。如果你需要处理大量的图像,或者进行复杂的图像处理操作,可能会发现PIL库的速度不尽如人意。
  2. 不支持一些高级功能:虽然PIL库提供了丰富的图像处理功能,但是它并不支持一些高级的图像处理操作,如特征检测、图像分割等。如果你需要进行这些操作,可能需要使用其他的图像处理库,如OpenCV。

 

3,PIL 库和OpenCV的区别

  1. 编程语言:PIL库是用纯Python编写的,而OpenCV主要是用C++编写的,并提供了Python的接口。如果您更熟悉Python,并且希望使用Python进行图像处理,那么PIL可能更适合您。并且PIL 的接口相对较为简单,特别适合一些简单的图像处理任务。对于一些不需要太多高级功能的应用,PIL 提供了直观的方法和易于使用的 API。
  2. 功能和算法:OpenCV提供了更丰富和先进的图像处理算法和函数,涵盖了从基本操作到高级计算机视觉任务的各个方面。而PIL 在功能上相对轻量,适合一些小型项目或者只需要进行基本图像处理的场景。如果你的需求主要是一些简单的图像操作,PIL 可能是更轻便的选择。
  3. 性能:由于OpenCV是用C++编写的,因此在处理大型图像和复杂计算任务时具有较高的性能优势。PIL库在处理大型图像时可能效率稍低。
  4. 生态系统:OpenCV拥有庞大的社区支持和丰富的文档资源,可以帮助您解决问题和学习。而PIL库的社区活动相对较少,文档资源相对较少。

 

4,如何使用PIL库

  首先是安装,比较简单:

pip install pillow

  

  下面是一个简单的示例,演示了如何使用PIL库来打开一个图像文件,然后将图像转换为灰度图,并保存到新的文件中:

from PIL import Image# 打开图像文件
img = Image.open('input.jpg')# 将图像转换为灰度图
img_gray = img.convert('L')# 保存图像到新的文件
img_gray.save('output.jpg')

  

  虽然 OpenCV 在计算机视觉和更复杂的图像处理任务中表现得非常强大,但选择使用哪个库通常取决于具体的需求和项目特点。在一些情况下,PIL 可能更为合适,而在其他情况下,特别是涉及到计算机视觉领域的任务,OpenCV 可能更具优势。

   总体来说,网上开源的一些计算机视觉中也使用PIL加载图像,所以有不得不学习的理由,话不多说,开干:

一:pillow模块的基本概念

  Pillow的官网地址:https://pillow.readthedocs.io/en/stable/,其实打开后,什么都有,只是都是英文,对于部分同学不方面而已。

 

  PIL:Python Imaging Library,已经是Python平台上的图像处理标准库了。由于PIL仅支持到Python2.7 ,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新版本的Python3.X,又加了许多新特性。因此,我们可以直接安装使用Pillow。

  PIL中所涉及的基本概念有如下几个:通道(bands)、模式(mode)、尺寸(size)、坐标系统(coordinate system)、调色板(palette)、信息(info)和滤波器(filters)。

1.1  通道——Image.getbands

  每张图片都是由一个或者多个数据通道构成。PIL允许在单张图片中合成相同维数和深度的多个通道。

  以RGB图像为例,每张图片都是由三个数据通道构成,分别为R、G和B通道。而对于灰度图像,则只有一个通道。

  对于一张图片的通道数量和名称,可以通过方法getbands()来获取。方法getbands()是Image模块的方法,它会返回一个字符串元组(tuple)。该元组将包括每一个通道的名称。

  Python的元组与列表类似,不同之处在于元组的元素不能修改,元组使用小括号,列表使用方括号,元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

  方法getbands()的使用如下:

from PIL import Image
im = Image.open("test.png")
print(im.getbands())
输出:
('R', 'G', 'B')

 

1.2  模式——Image.mode

  图像的模式定义了图像的类型和像素的位宽。当前支持如下模式:

1:1位像素,表示黑和白,但是存储的时候每个像素存储为8bit。L:8位像素,表示黑和白。P:8位像素,使用调色板映射到其他模式。RGB:3x8位像素,为真彩色。RGBA:4x8位像素,有透明通道的真彩色。CMYK:4x8位像素,颜色分离。YCbCr:3x8位像素,彩色视频格式。I:32位整型像素。F:32位浮点型像素。PIL也支持一些特殊的模式,包括RGBX(有padding的真彩色)和RGBa(有自左乘alpha的真彩色)。

  可以通过mode属性读取图像的模式。其返回值是包括上述模式的字符串。

  属性mode的使用如下:

from PIL import Image
im = Image.open("test.png")
print(im.mode)
输出:
'RGB'

  

1.3  尺寸——Image.size

  通过size属性可以获取图片的尺寸。这是一个二元组,包含水平和垂直方向上的像素数。

  属性mode的使用如下:

from PIL import Image
im = Image.open("test.png")
print(im.size)
输出:
(670, 502)

  

1.4  坐标系统

  在PIL(或Pillow)中,图像的坐标系统遵循常见的数学坐标系,其中左上角是原点(0, 0),x轴向右增长,y轴向下增长。这意味着图像的左上角具有坐标 (0, 0),而右下角的坐标是 (width-1, height-1)

  以下是一个简单的示例说明PIL的坐标系统:

from PIL import Image, ImageDraw# 创建一个白色背景的图像
width, height = 200, 100
image = Image.new("RGB", (width, height), "yellow")# 创建一个ImageDraw对象,即获取图像的绘制对象
draw = ImageDraw.Draw(image)# 在图像中心绘制一个红色矩形
rect_width, rect_height = 50, 30
left = 0
top = (height - rect_height) // 2
right = left + rect_width
bottom = top + rect_heightdraw.rectangle([left, top, right, bottom], fill="red")# 保存图像
# image.save("coordinate_example.png")# 显示图像
image.show()# 显示坐标系
print(f"左上角坐标:(0, 0)")
print(f"右下角坐标:({width-1}, {height-1})")# 输出结果
# 左上角坐标: (0, 0)
# 右下角坐标:( 199, 99)

  输出图像:

 

1.5  调色板——Image.palette

  在PIL(Python Imaging Library)中,调色板(Palette)是一种用于存储和管理颜色映射的机制。调色板通常与图像的索引颜色模式一起使用,这意味着图像的每个像素值不直接表示颜色,而是作为索引来查找调色板中的实际颜色。

  以下是有关调色板的一些重要概念和说明:

  1. 索引颜色模式:

    • 在索引颜色模式中,图像的每个像素值都是一个索引,该索引对应于调色板中的颜色。
    • 通常,索引颜色模式用于节省存储空间,特别是对于包含有限颜色集的图像。
  2. 调色板的组成:

    • 调色板是一个包含颜色信息的数据结构,通常由颜色元组组成。颜色元组可以是RGB(红、绿、蓝)格式,也可以是其他颜色表示格式。
    • 对于每个索引,调色板中都有一个与之对应的颜色。
  3. 使用调色板的图像格式:

    • 一些常见的使用调色板的图像格式包括GIF和PNG-8。这些格式在保存图像时使用调色板,而不是直接存储每个像素的完整颜色信息。
  4. 图像的调色板属性:

    • PIL中的图像对象具有调色板属性,通过该属性可以获取和设置图像的调色板。
    • 使用 image.getpalette() 方法可以获取图像的调色板,而 image.putpalette() 方法可以设置调色板。

  以下是一个简单的示例,演示如何使用PIL中的调色板:

from PIL import Image# 创建一个调色板
palette = [255, 0, 0,  # Red0, 255, 0,  # Green0, 0, 255]  # Blue# 创建一个8x8的图像,使用调色板和索引颜色模式
image = Image.new("P", (8, 8))
image.putpalette(palette)# 设置图像的像素值(索引)
pixels = [0, 1, 2, 0, 1, 2, 0, 1,1, 2, 0, 1, 2, 0, 1, 2,2, 0, 1, 2, 0, 1, 2, 0,0, 1, 2, 0, 1, 2, 0, 1,1, 2, 0, 1, 2, 0, 1, 2,2, 0, 1, 2, 0, 1, 2, 0,0, 1, 2, 0, 1, 2, 0, 1,1, 2, 0, 1, 2, 0, 1, 2]image.putdata(pixels)# 显示图像
image.show()

  这个例子创建了一个调色板,然后使用索引颜色模式创建了一个8x8的图像,并通过设置像素值(索引)来使用调色板中的颜色。

1.6  信息——Image.info

  使用info属性可以为一张图片添加一些辅助信息。这个是字典对象。加载和保存图像文件时,多少信息需要处理取决于文件格式。

属性info的使用如下:

from PIL import Image
im = Image.open("test.jpg")
print(im.info)
输出:
{'jfif': 257, 'jfif_version': (1, 1), 'jfif_unit': 0, 'jfif_density': (1, 1)}

  

1.7  滤波器

  对于将多个输入像素映射为一个输出像素的几何操作,PIL提供了四个不同的采样滤波器。

NEAREST:最近滤波。从输入图像中选取最近的像素作为输出像素。它忽略了所有其他的像素。BILINEAR:双线性滤波。在输入图像的2x2矩阵上进行线性插值。
注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。BICUBIC:双立方滤波。在输入图像的4x4矩阵上进行立方插值。
注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。ANTIALIAS:平滑滤波。这是PIL 1.1.3版本中新的滤波器。对所有可以影响输出像素
的输入像素进行高质量的重采样滤波,以计算输出像素值。在当前的PIL版本中,这个滤
波器只用于改变尺寸和缩略图方法。
注意:在当前的PIL版本中,ANTIALIAS滤波器是下采样(例如,将一个大的图像转换为
小图)时唯一正确的滤波器。BILIEAR和BICUBIC滤波器使用固定的输入模板,用于固
定比例的几何变换和上采样是最好的。

  Image模块中的方法 resize() 和 thumbnail()用到了滤波器。

  方法resize() 的使用如下:

方法resize()的定义为:resize(size, filter=None)=> image
from PIL import Image
im = Image.open("test.png")
print(im.size)
im_resize = im.resize((256,256))
print(im_resize.size)
输出:
(670, 502)
(256,256)

  对参数filter不赋值的话,方法resize()默认使用NEAREST滤波器。如果要使用其他滤波器可以通过下面的方法来实现:

from PIL import Image
im = Image.open("test.png")
print(im.size)
im_resize0 = im.resize((256,256), Image.BILINEAR)
print(im_resize0.size)
im_resize1 = im.resize((256,256), Image.BICUBIC)
print(im_resize1.size)
im_resize2 = im.resize((256,256), Image.ANTIALIAS)
print(im_resize2.size)输出:
(670, 502)
(256,256)
(256,256)
(256,256)

  

 

2,Image对象

2.1  实例化对象

  直接读取图片

from PIL import Image# 导入图像
img_path = r"book.png"
img = Image.open(img_path)# 展示图像
im.show()

  

2.2 格式转换——save方法

  save方法用于保存图像,当不指定文件格式时,它会以默认的图片格式来存储;如果指定图片格式,则会以指定的格式存储图片,语法如下:

im = PIL.Image.open(r"book.jpg")# 保存图片
# fp: 图片的存储路径,包含图片的名称,字符串格式
fp = "book_save.jpg"  
# format:可选参数,可以指定图片的格式
im.save(fp, format=None)  

  

 

2.3  格式转换——Convert方法

  注意:并非所有的图片格式都可以用 save() 方法转换完成,比如将 PNG 格式的图片保存为 JPG 格式,如果直接使用 save() 方法就会出现错误,引发错误的原因是由于 PNG 和 JPG 图像模式不一致导致的。其中 PNG 是四通道 RGBA 模式,即红色、绿色、蓝色、Alpha 透明色;JPG 是三通道 RGB 模式。因此要想实现图片格式的转换,就要将 PNG 转变为三通道 RGB 模式。

  Image 类提供的 convert() 方法可以实现图像模式的转换。该函数提供了多个参数,比如 mode、matrix、dither 等,其中最关键的参数是 mode,其余参数无须关心

  语法:

im.convert(mode, params)  # 转换模式
im.save(fp)  # 保存图片

  

 2.4  图像缩放

 在图像处理过程中经常会遇到缩小或放大图像的情况,Image 类提供的 resize() 方法能够实现任意缩小和放大图像

  语法:

im_new = im.resize(size, resample=image.BICUBIC, box=None, reducing_gap=None)  # 缩放后的图片
im_new.show() 

  

2.5  图像的分离和合并

  图像(指数字图像)由许多像素点组成,像素是组成图像的基本单位,而每一个像素点又可以使用不同的颜色,最终呈现出了绚丽多彩的图像 ,而图像的分离与合并,指的就是图像颜色的分离和合并

图像分离:split方法

  示例:

im = PIL.Image.open(r"magic_h03.jpg")# split 方法使用较简单,分离通道
r, g, b = im.split()  
r.show()
g.show()
b.show()

  

图像合并:merge方法

  Image 类提供的 merge() 方法可以实现图像的合并操作。注意,图像合并,可以是单个图像合并,也可以合并两个以上的图像

  示例:

im_merge = PIL.Image.merge(mode, bands)
im_merge.show()

  

图像合并:blend方法

  Image 类也提供了 blend() 方法来混合 RGBA 模式的图片(PNG 格式)

  语法:

PIL.Image.blend(image1,image2, alpha)

  

2.6  图像裁剪

  Image 类提供的 crop() 函数允许我们以矩形区域的方式对原图像进行裁剪

  语法:

im_crop = im.crop(box=None)  # box 代表裁剪区域
im_crop.show()

  box 是一个有四个数字的元组参数 (x_左上,y_左下,x1_右上,y1_右下),分别表示被裁剪矩形区域的左上角 x、y 坐标和右下角 x,y 坐标。默认 (0,0) 表示坐标原点,宽度的方向为 x 轴,高度的方向为 y 轴,每个像素点代表一个单位

 

3,代码实战

3.1 图像的属性的打印示例

  注意:源文件的文件格式。如果是由PIL创建的空图像,则其文件格式为None,即 im.format ⇒ string or None

  示例代码如下:

import PIL.Imageim = PIL.Image.open(r"harden.png")print(im.size)  # 查看图片大小, 按照像素数计算。它的返回值为宽度和高度的二元组(width, height)
print(im.readonly) # 查看是否为只读,1为是,0为否 print(im.format) # 查看图片的格式, 输出为 'png'
print(im.info) # 查看图片的相关信息 print(im.mode) # 查看图片的模式print(im.mode)  # 表明图像所使用像素格式, 属性典型的取值为“1”,“L”,“RGB”或“CMYK”
print(im.palette)  # 颜色调色板表格。如果图像的模式是“P”,则返回ImagePalette类的实例;否则,将为None。

  

 

3.2  使用PIL进行灰度化+二值化

  代码如下:

from PIL import Image#  load a color image
im = Image.open('durant.jpg' )#  convert to grey level image
Lim = im.convert('L' )
Lim.save('grey.jpg' )#  setup a converting table with constant threshold
threshold = 185
table = []
for i in range(256):if i < threshold:table.append(0)else:table.append(1)# convert to binary image by the table
bim = Lim.point(table, '1' )bim.save('durant_grey.jpg' )

  原图图片效果展示:

 

  灰度化图片效果展示:

  二值化图片效果展示:

 

3.2  图像转换示例

  代码如下:

 

例子1:
from PIL import Image
im1 = Image.open("jing.jpg")
print(im1.mode)
im_c = im1.convert("1")
im_c.save("he.jpg")
print(im_c.mode)
输出:
注:将“RGB”模式的im01图像,转换为“1”模式的im_c图像。定义3:im.convert(mode,matrix) ⇒ image
含义3:使用转换矩阵将一个“RGB”图像转换为“L”或者“RGB”图像。变量matrix为4或者16元组。
例子3:下面的例子将一个RGB图像(根据ITU-R709线性校准,使用D65亮度)转换到CIE XYZ颜色空间:
from PIL import Image
im1 = Image.open("jing.jpg")
im1.mode
rgb2xyz = (0.412453, 0.357580, 0.180423, 0,0.212671, 0.715160, 0.072169, 0,0.019334, 0.119193, 0.950227, 0 )
im_c3 = im1.convert("L", rgb2xyz)
im_c3.save("he.jpg")
print(im_c3.mode)
输出:
L

  

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

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

相关文章

Angular-测试驱动开发-全-

Angular 测试驱动开发(全)原文:zh.annas-archive.org/md5/60F96C36D64CD0F22F8885CC69A834D2 译者:飞龙 协议:CC BY-NC-SA 4.0前言 本书将为读者提供一个关于 JavaScript 测试驱动开发(TDD)的完整指南,然后深入探讨 Angular 的方法。它将提供清晰的、逐步的示例,不断强…

python中的装饰器,迭代器,生成器之间的关系

一、装饰器 装饰即修饰,意指为其他函数添加新功能; 装饰器的本质就是函数 作用是为其他函数添加新功能,如计算该函数运行时长 装饰器遵循原则: 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不能修改被修饰函数的调用方式 装饰器的实现 = 高阶…

RepVGG-GELAN | 融合 VGG、ShuffleNet 与 YOLO 图像检测的准确性及效率再上一层!

前言 基于YOLO的目标检测算法在速度和准确性之间取得了显著的平衡。然而,它们在脑肿瘤检测中的应用仍然未被充分探索。本研究提出了RepVGG-GELAN,这是一种新型的YOLO架构,通过集成RepVGG,一种重新参数化的卷积方法,特别关注于医学图像中的脑肿瘤检测。RepVGG-GELAN利用Rep…

有关字符串的函数接口

目录strstr函数,用于从一个字符串中查找子串strtok函数,用于分割字符串 strstr函数,用于从一个字符串中查找子串strtok函数,用于分割字符串

24考研成电860——记我消失的一年

考研经验分享成电考研860经验帖 本人情况介绍 本人于今年毕业于某双非院校计算机系,绩点3.3,甲级联赛有两个国三。刚开始是想保研的,大一绩点是3.8,但是由于院校保研名额不是很多,如果全力冲保研的话风险很大,高绩点不代表你能找到好的工作(但是如果你能出国的话我极力推…

最短路径

拓扑序 有这样一个问题:我们给定一张 \(n\) 个点 \(m\) 条边的有向无环图(DAG),请求出从 \(1\) 号结点出发,到达任意结点的最短路径,保证 \(s\) 可以到达任意结点,\(n,m\leq 10^7\)。我们以下面这张图为例。如果我们想求 \(1 \rightarrow 4\) 的路径, 我们不难发现,找…

强大且免费的抠图网站(强烈安利!)

今天想把下载下来的图片进行抠图上传,找了好久没找到好用的,不是功能单一就是收费( 囊中羞涩 ),猛然间,发现一个神奇的网站,名叫 易可图!!易可图 是一款全方位的免费图片编辑网站,包含抠图、裁剪、拼接、压缩等常用功能,易可图抠图功能只需用户上传照片,就能一…

平行关系转化思维导图

线线、线面、面面平行关系转化思维导图前言 使用方法:如果想得到更好的显示效果,可以点击全屏按钮,已经实现电脑端、手机端的适配,效果很好;电视端没有实现适配,Ipad端的适配没有测试; 思维结构图全屏

adb

Android调试桥接器,简称adb(Android debug bridge)列出所有已连接的设备命令:adb devices运行指定的设备的shell命令:adb -s serialNumber shell从本地主机拷贝文件到远程主机命令:adb -s serialNumber push C:\Users\coolkit\Desktop\新建文件夹\test.txt /data从远程主…

[Java基础复习]注解

一、什么是注解注解是JDK1.5才引入的,Java增加了对元数据(描述数据的数据)的支持,也就是注解。 注解可以标注在类,成员变量,方法、形参上等。 注解可以做到在不改变代码逻辑的前提下在代码中嵌入补充信息。 这些信息被保存在注解的“name=value”键值对中。 框架=反射+注解…

基于Python的性能分析

1、什么是性能分析 字面意思就是对程序的性能,从用户角度出发就是运行的速度,占用的内存。 通过对以上情况的分析,来决定程序的哪部份能被优化。提高程序的速度以及内存的使用效率。 首先我们要弄清楚造成时间方面性能低的原因有哪些沉重的I/O操作,比如读取分析大文件,长时…

基于Azure DevOps 的 CICD 项目部署(.Net Core)

基于Azure DevOps 的 CICD 项目部署(.Net Core)使用微软的 来进行CICD 链接:https://dev.azure.com创建新项目创建项目名称选择仓库地址选择空模板创建代理池按照以下步骤把代理部署到服务器上 ![连接你的服务器创建新的文件夹 mkdir myange cd myagent可通过链接下载文件…