新大榭论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

《新大榭》- 创大榭地方网络社区先锋品牌 新大榭始终专注于地方网络社区平台的建设 关于我们- [大记事]- 留言建议- [新手报道]

新大榭软件管家 V5.8 Excel版 微信版 发布 财务/仓库/生产/销售/采购/行政/人事/校园 客服中心 - 办公软件 - 网站设计 - 广告招商

新大榭镜像 - 官方Web实验室 - 加入收藏 - 设为首页 广告是为了更好的发展 欢迎我区企业及商家赞助本站 首页文字黄金广告位(赞助)公益广告免费发布

新大榭论坛 门户 查看主题

7410 - Python库 AP095【PIL】模块快速入门

发布者: admin | 发布时间: 2021-7-12 18:38| 查看数: 941| 评论数: 0|帖子模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转新大榭论坛!

您需要 登录 才可以下载或查看,没有账号?注册

x
概述
+ d6 D$ q! J. Q( b' O% T! \) w" `, NPIL库主要用途+ f( |. g! M9 ^0 s) L9 Y& o
  • 图像存储
    % t/ H) H& G" n4 TPIL适合图像归档和图像批量处理,你可以使用它建立缩略图,转换格式,打印图片等。: n( K; ~* y: M
    现在的版本可以识别和读取大量的图片格式,写入常用的转换和表示格式。
  • 图像显示6 k/ i! J! ?1 I. w; Q9 i
    支持多个其他工具包的展示,提供了show() 方法,可以保存图像到磁盘并调用外显示。它将图像保存到磁盘,并调用外部显示工具。
  • 图像处理(重点)" g; A% X) v4 C5 s( z2 s
    包含了基本的图像处理功能,包括点操作,使用内置卷积内核过滤,色彩空间转换。
    8 M9 p! o0 A0 [7 j支持更改图像大小、旋转、任意仿射变换。
    3 i% F% C( x5 ?9 `" U2 S5 {$ m8 j
" k) g4 h. y9 }
教程: f+ n5 S1 [. Y1 k
注意:PIL导包是用的 from PIL import Image,但是安装的时候并不是这个库名,小伙伴执行下面的PIL安装命令即可,正确的包名为:Pillow,执行下面语句安装即可,出现版本号表示安装成功:
  1. pip install Pillow
复制代码
1. 使用 Image 类
- W' V3 x3 {6 `- uImagePIL 中最重要的类,用于从文件加载图像、处理其他图像、从 scratch 创建图形等:
2 W! I( D: o* q* p
* J" @' f* q$ C/ v6 _
1.1 加载图像
' I# A4 J6 o* M. q7 b. t6 L2 J; e4 B从文件加载图像,若打开错误返回 IOError
6 @2 x& b. _3 ?) C7 j+ ]  }
  1. from PIL import Image
    5 e- E: s! T4 ]0 y/ I& V
  2. im = Image.open('lena.ppm')
复制代码
从打开的文件中读取
  1. with open("hopper.ppm", "rb") as fp:
    ( ~% f+ m; x& }  N0 W
  2.     im = Image.open(fp)
复制代码
如果是从二进制流中读取,则需要先通过 io 转换成文件流,或者使用 StringIO
# g, B( r* F* z# M4 d1 E
  1. import io
    3 L! k0 A. U. X' x
  2. im = Image.open(io.BytesIO(buffer))
    0 s0 }0 a* n, v: C$ ?$ X
  3. import StringIO$ Z- D9 t1 f/ ^- M: _/ u4 ^7 S
  4. im = Image.open(StringIO.StringIO(buffer))
复制代码
tar档案中读取' Z7 a8 n# ^" X9 h
  1. from PIL import Image, TarIO* q& U0 y6 }4 ^4 @" d7 f0 T

  2. 4 I- \; f8 i6 k7 o. T# P( G
  3. fp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")
    * j! {  w) v  ]
  4. im = Image.open(fp)
复制代码
* o  m& I1 T0 L- y
1.2 图片属性

7 Y: e+ e: P4 m9 S# M
成功加载后会返回一个 Image 对象,可观察以下属性:/ a$ ~4 R9 G! r+ G! Y0 h! o
format: 判断图片来源,即 ppm/png 等 (若不是从文件读取则返回 None);
0 H! [: f% o% _6 M, v5 qsize: 查看宽度和高度(二元组 tuple,单位是 px );
7 X& r/ }# F5 t6 C/ P, Imode: 定义图像波段数与名称(像素类型和深度),常见有 L 灰度图像,RGP 真彩色图像, CMYK 出版图像
) s2 J7 ^  Q7 G
  1. print(im.format, im.size, im.mode)
    % v8 h0 l. h. Y2 j* \1 B* V2 u
  2. # PPM (512, 512) RGB
复制代码
. y, I" D/ v" Z& }  S6 P' _
1.3 图片显示
  1. # 自带方法:
    6 P- a" \- _! _- I1 s
  2. im.show()
    # s  ]4 g6 c: t0 p% L
  3. # 使用 matplotlib 显示:
    " }' E  ?3 n, L1 u( ?* N( Y! a5 j
  4. import matplotlib.pyplot as plt
    9 `$ f+ G: F3 X) ~
  5. plt.imshow(im)
    % U, p# ]& F+ s# O9 M
  6. plt.show()
复制代码

* I8 M2 H9 a) v4 y* V1.4 读写图像

. n1 X/ |3 Z5 d2 N! ~, @/ kPIL 库支持大量图片格式。使用 Image 模块的 open() 函数从磁盘读取文件。你不需要知道文件格式就能打开它,PIL 能够根据文件内容自动确定确定文件格式。
4 A1 @0 @" y+ u, H! M; f$ ~2 Y
5 s. ]; B( _' B+ U0 I保存文件时使用 Image 类的 save() 方法。此时文件名就变得重要,除非你指定格式,PIL 将会以文件名的扩展名作为格式保存。save() 方法的第二个参数可以指定文件格式,如果你使用非标准的扩展名你必须这样做。
  1. # 转换文件为JPEG:2 ]8 B4 a/ z8 D6 R
  2. import os, sys
    1 t. N( t) Q( \5 e' k& o! K
  3. from PIL import Image1 y. [! @" L# W6 H5 `

  4. $ G. ?+ L1 b2 _5 I% ~& H
  5. for infile in sys.argv[1:]:9 h, J( ^: }+ p7 O) j5 P2 O
  6.     f, e = os.path.splitext(infile)
    " R4 `! c% T5 }( ^4 I2 p
  7.     outfile = f + ".jpg"( R  `3 K0 h8 \5 K) R# h
  8.     if infile != outfile:, `) G6 z4 r/ J0 V4 w9 N! A
  9.         try:5 J3 Q3 g6 _$ |2 K" O3 }
  10.             Image.open(infile).save(outfile)
    ! l3 g' F1 r3 @& [; ~# F, z, [
  11.         except IOError:
    / o% S- q* \, R/ N6 ~
  12.             print("cannot convert", infile)
    4 i* `5 ]4 A! A8 L& x6 N- E" s! J

  13. 9 V4 [8 S1 [/ r$ Q1 G
复制代码
# C, q  `9 w, I& y. |
2. 图像处理) U0 G: h4 {: B1 [
2.1 剪切、粘贴、合并图像* j. J0 d7 f5 ?. `! U
crop():从图像中提取子矩形。box 坐标分别是(左,上,右,下)的位置,下例取出的是 300*300 像素的矩阵" T( F  j( B. j; e( _: K0 S5 B
  1. box = (100, 100, 400, 400)
      X) _' k2 W. ^  Q' L
  2. region = im.crop(box)
复制代码
paste():粘贴;粘贴区域是大小必须完全匹配,但模式不需要匹配(模式在粘贴时会自动转换)。粘贴时可以选择透明度,0 对应完全透明,255 对应不透明(默认)。
4 W$ f. g  e) O% I4 B
  1. region = region.transpose(Image.ROTATE_180)  # 旋转180度( k+ D7 c, t2 ~0 _7 @' A
  2. im.paste(region, box)
复制代码
实例:滚动图像,使图像循环向左滚动(即将左边一小节一直粘贴到图像的右边)$ n% w; C3 \. ^! B
  1. from PIL import Image3 @) _* n7 n2 h3 k+ E" ~
  2. ; Z& @  n2 J8 v( o% i4 M
  3. def roll(image, delta):/ y2 F. _/ r6 ?/ A. d! U
  4.     """Roll an image sideways."""
    : C  _( q& Y, k3 H5 B3 S- U
  5.     xsize, ysize = image.size, E/ {1 w% Z5 O" g; s- p

  6. : y) p" b0 e6 ~( [
  7.     delta = delta % xsize# W3 I( ~% R1 t( i. g; }5 }
  8.     if delta == 0: return image
    8 ~% k- c  |, ?9 |' s  o: d6 W

  9. 6 N  g+ s; f5 K0 j% v7 a, G8 p
  10.     part1 = image.crop((0, 0, delta, ysize))
    % I+ x2 ^  i* o; E2 Q
  11.     part2 = image.crop((delta, 0, xsize, ysize))
    6 O) k0 e* s9 P; F5 c  q- S
  12.     part1.load()
      r2 {; l( @8 R* `% V
  13.     part2.load()7 H, w9 ^' ~& Q% I
  14.     image.paste(part2, (0, 0, xsize-delta, ysize))1 y+ z3 l5 i, S6 }
  15.     image.paste(part1, (xsize-delta, 0, xsize, ysize))! u# Q0 I7 D0 m' S2 a

  16.   e+ Q" V4 W/ F
  17.     return image) B' R# n" L. q, H, {
  18. $ \4 d7 Y  l! m: R. c/ `
  19. im = Image.open("demo.jpg")2 \. K  t1 p8 h2 h" [$ @1 F
  20. im = roll(im,100)
    5 ?% p  P: Q2 Y; X* O/ L( z
  21. im.show()
复制代码
split():用于对图像进行波段拆分,如针对 RGB 图像,拆分后将生成3幅单波段图像,对单波段图像则返回本身。
: H, W* G: w. j/ y1 ]8 Omerge():用于将多个波段图像合并成新图像。
: ^. Z$ S: c$ e" P
  1. r, g, b = im.split()* ]; B( H5 m( |& |: k& I4 O
  2. im = Image.merge("RGB", (b, g, r))
复制代码
/ i- k* d  |) K5 X" G+ j
2.2 几何变换
: c2 ~; r) [# o7 G2 Z2 \
resize():给定目标尺寸元组,对图像进行拉伸或压缩
0 x  I( K) |* }rotate():给定旋转角度,对图像进行逆时针旋转/ R: t( l: ~! p: \7 s3 |) J
  1. out = im.resize((128, 128))! [- ]( I( q' o
  2. out = im.rotate(45) # degrees counter-clockwise
复制代码
transpose():使用一些固定方法对图像进行变换: s/ T* d* g0 J+ \
  1. out = im.transpose(Image.FLIP_LEFT_RIGHT)' y: n+ {9 F2 ~* C3 Q
  2. out = im.transpose(Image.FLIP_TOP_BOTTOM)
    - U% \) ]3 A8 M# k4 x
  3. out = im.transpose(Image.ROTATE_90)
    8 d3 ]! D6 _7 C' ~) l
  4. out = im.transpose(Image.ROTATE_180)
    1 i+ T! a9 O3 Q
  5. out = im.transpose(Image.ROTATE_270)
复制代码
: b- V' T9 W' G) x; U: S, d, k3 L  w
2.3 颜色模式转换

% H' k5 B* m' X  Xconvert():对图像进行不同颜色模型的转换,如常用的 LRGB 之间的转换;
1 S( }* {# `2 V7 i0 d: n
  1. im = Image.open("hopper.ppm").convert("L")
复制代码

* f3 c; w! k7 c6 B$ Q3. 图像增强
1 a/ G, A2 `& u* x
3.1 滤波器7 H8 Q( K2 m7 p9 w- M" w
ImageFilter 模块包含许多可以与 filter() 方法一起使用的预定义滤波器
5 M; m5 Q+ F/ U5 [. p+ u
  1. from PIL import ImageFilter& X( b# k9 H* ~( O2 D
  2. out = im.filter(ImageFilter.DETAIL)
复制代码
可用滤波器一览,具体效果看
BLUR:模糊滤波$ `/ a0 |- G/ v3 p
CONTOUR:轮廓滤波# A9 {0 e* r1 [8 t' E
DETAIL:细节滤波
. k, j& S! [0 H6 H5 MEDGE_ENHANCE:边界增强滤波
" Q, S/ f1 H: [1 bEDGE_ENHANCE_MORE:深度边缘增强滤波9 g7 V9 q+ ^- G! i& I6 e
EMBOSS:浮雕滤波% C& @$ s- s5 t: r* r- f
FIND_EDGES:寻找边界滤波(找寻图像的边界信息)' |5 S# u8 k$ h; |4 @+ L
SMOOTH:平滑滤波8 d8 v; y. n0 l* \* Z; k
SMOOTH_MORE:深度平滑滤波
3 U2 \  v  l* n8 y* z  ESHARPEN:锐化滤波
2 ^( c8 \& i- i) C* qGaussianBlur:高斯模糊- o' a) z: @. {. O) {1 V# n1 d: f* j
UnsharpMask:反锐化掩码滤波
! [0 K5 c) x5 \' b+ c2 r4 x(radius:模糊半径;percent:反锐化强度(百分比);threshold:被锐化的最小亮度)2 e2 G* H) K! i  f8 ^, V
Kernel:卷积核滤波
/ c& }: z" M" t% B(size:核的大小;kernel:核权值序列如33的为;scale:缩放因子;offset:偏移量)9 _8 X8 {8 H  n5 y  g
RankFilter:排序滤波; u, `; j+ X2 r
(size:核的大小;rank:排序序号)
' d7 g2 C" o& ~Kernel:卷积核滤波
7 v4 F! P0 r+ @+ g; q( ^/ C: j(size:核的大小;kernel:核权值序列如33的为;scale:缩放因子;offset:偏移量)0 ?, h2 J# A  u+ ^. |$ s
MinFilter:最小值滤波器0 W5 g4 u3 S$ e4 P) R# x0 G3 v
MedianFilter:中值滤波
3 ?) p6 a5 _  T* Z" b3 D: o5 [MaxFilter:最大值滤波% ~. S) ]# V" s! ?
ModeFilter:模式滤波

  s; D" x, g0 |# v' Q3.2 点操作
* H/ {; e+ ?8 Q5 _point() : 方法可用于转换图像的像素值(例如图像对比度操作)。在大多数情况下,期望一个参数的函数对象可以传递给此方法。每个像素都根据该功能进行处理:
" E: _2 a4 _: g; J$ N2 G
  1. # multiply each pixel by 1.27 [8 g' E  Y$ E; \6 {) n
  2. out = im.point(lambda i: i * 1.2)
复制代码
实例:处理单个色带:$ K( ]7 N# L$ F0 T  q: Q5 P' r/ e
1. 将 red < 1000 否则 255! A- c: z6 {: b/ h4 z$ O, T
2. green 变成原来 0.7
  1. # split the image into individual bands
    " ^) b- W' Y4 U2 i
  2. source = im.split(): n5 O+ L3 x6 {6 H, U( ~
  3. * y3 I! f- }3 k3 F) a) l& [
  4. R, G, B = 0, 1, 2, [& N+ T& }" v2 M% ?1 k( M
  5. * h) W4 z; V/ o) I, ?/ O5 X
  6. # select regions where red is less than 100
    4 t% W" A+ P% V  h
  7. mask = source[R].point(lambda i: i < 100 and 255)
    8 O: B# _- A0 g9 H( C
  8.   s" z9 Y) a  T* J0 z5 A5 ]& R- x; ?
  9. # process the green band
    ( f4 @' ?) w9 l; Q8 q0 Y& s: V& g
  10. out = source[G].point(lambda i: i * 0.7)
    . S8 w5 S+ }$ m  V. s) a; X- ?& [+ D

  11. " D) ^' s; ^& q9 |0 D
  12. # paste the processed band back, but only where red was < 100" z8 Q% g7 a. A9 h5 I
  13. source[G].paste(out, None, mask)$ z0 @- p) y$ W+ c

  14. , R1 W! ]$ |8 J# t1 [
  15. # build a new multiband image% x9 p% W5 g+ ^8 \; y  |4 R( ]5 C
  16. im = Image.merge(im.mode, source)! q; i$ D( H* f5 q: U7 X3 p
复制代码
. M' ?; S0 `2 s, x- V/ `8 F
3.3 增强
- q5 P( \. o. w
对于更高级的图像增强,您可以使用 ImageEnhance 模块中的类。从图像创建后,可以使用增强对象快速尝试不同的设置。您可以用这种方式调整对比度,亮度,色彩平衡和清晰度。
  1. from PIL import ImageEnhance
    * m1 ]" j2 U3 C- y
  2. 8 U  m3 n+ t8 ]7 V) L
  3. enh = ImageEnhance.Contrast(im)$ d  r) E8 u9 f* c& |: J6 i6 Y
  4. enh.enhance(1.3).show("30% more contrast")
复制代码
! s$ d6 `  S. X
4. 图像序列
5 w# ^2 o4 j" ~# \+ Q5 a& W; ~
Python图像库包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括FLI/FLC, GIF和一些实验格式。 TIFF文件也可以包含多个帧。1 P& {. c3 Y) ~3 R( D) \+ B, X' \
当你打开一个序列文件时,PIL自动加载序列中的第一帧。您可以使用 seek tell 方法在不同的帧之间移动。注意当前版本库中的大多数驱动程序只允许您寻找下一帧。要倒回文件,您可能必须重新打开它。2 }% q$ M5 v( J) _8 J
读序列:
  1. from PIL import Image3 J$ I/ N& K/ ?& j0 Z: i$ ]8 @
  2. 4 j( i" {8 l$ K* l& X" ^
  3. im = Image.open("animation.gif")
    ' K9 ^9 ^5 p' m
  4. im.seek(1) # skip to the second frame! G: f$ C/ i5 N# v
  5. % U6 D2 m& o6 v; ?
  6. try:' E4 e* F$ f' @1 C
  7.     while 1:' U  V6 H0 v; Q' e
  8.         im.seek(im.tell()+1)
    ) }4 T" G1 L& U% B0 x8 d% H
  9.         # do something to im
    ( [; J$ u" Z7 u
  10. except EOFError:) T% M/ d; h6 ]' F$ n7 z
  11.     pass # end of sequence
复制代码
使用 for 遍历:- ~3 E: Z  C7 |: }
  1. from PIL import ImageSequence
    ( L! |3 @" b9 y$ x
  2. for frame in ImageSequence.Iterator(im):
    $ ~8 O. N/ |/ `; c2 r
  3.     # ...do something to frame...
复制代码
》》》待续 ~+ q3 L" @/ g1 C

最新评论

新大榭七周年,感谢由您!

文字版|小黑屋|新大榭 ( 浙ICP备16018253号-1 )|点击这里给站长发消息|

GMT+8, 2024-4-23 16:23 , Processed in 0.083659 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表