Python处理图像文件的实用姿势

那些人人称道的美丽,里面都有PS的痕迹。

人是视觉型动物,每个人都有自己的审美标准,那些共同的准则形成了社会潮流。

随着计算机技术升级,我们现在可以用手机随时拍出漂亮的照片。

“PS”技术不再局限于“电脑”,而且计算机慢慢开始拥有了自己的“视觉”能力。

计算机视觉,就是让计算机读懂图像内容,是人工智能的一部分。

所以,用Python处理图像的场景,有两大类:

  1. 批量自动化处理图像,如裁剪、滤镜、旋转等效果叠加。
  2. 智能识别图像内容,如人脸识别、人物识别等,用“PS”术语可以叫“自动抠图”。

处理图像,其实就是处理色彩的数据,最常见的比如RGB格式

当图像要保存到磁盘时,人们会用压缩算法缩小数据占用空间,再次读取和显示时就解压缩还原。

Python处理图像的模块主要有3类:

  • Pillow,即PIL最活跃分支,普及度高,提供多种图像格式处理能力。还有不少依赖于它的项目应用,如之前介绍的openpyxlpython-pptx,以及图像增强工具 Augmentor
  • scikit-image,是科学计算生态scipy的图像能力补充。
  • OpenCV,Intel发起的计算机视觉库,用C++实现后提供Python接口封装。

从性能角度看OpenCV最强,但Pillowscikit-image的接口更简单,尤其是Pillow,不需要直接面对numpy.ndarray的矩阵数据。当然了,图像处理到深处,那就都是数学,尤其是线性代数。

好在图像研究已经很多年,我们从应用角度看,重点是掌握如何用Python解决日常工作中的问题。

选择哪一类模块,需要从实际应用需求和知识背景2个角度出发:

  • 只做一些简单图片处理,比如大小、基本滤镜等,pillow足够。
  • 需要灵活自定义高级滤镜,或研究图像算法,scikit-imageopencv更适合,有不少三方模块底层使用了opencv,所以根据具体应用情况可以穿插使用。只不过需要注意opencv内部数据不是RGB顺序,而是BGR顺序。
  • 绘制图表,比如折线图、饼图等,不需要以上模块,用matplotlib更适合。

对于初学者,建议先用pillow,不够用时再从scikit-imageopencv中寻找解决算法。

此外,虽然三者内部图像数据存储方式不同,但可以互相转换。

本文重点介绍pillow模块用法,部分兼用opencvscikit-image

模块安装:

  • pip install pillow
  • pip install scikit-image
  • pip install opencv

本文包含如下常见应用场景:

  • 基本使用:打开、显示、保存,灰度化、锐化
  • 数据互转:三个类库中图像数据互相转换
  • 基本图像处理:调整大小、旋转、翻转、裁剪
  • 图像滤镜:换底色、各类风格,如漫画、油画、漫画头像、复古、黑白
  • 实战应用:屏幕截图、抠图、批量加水印
  • 智能应用:人脸识别,如带口罩、情绪

基本使用

先来分别感受下pillowscikit-imageopencv三个模块的基本使用方式。

包括:读写文件、灰度化和锐化图像。

Pillow基本使用
import pathlib
from PIL import Image, ImageFilter
path = pathlib.Path('~/dev/python/python1024/data/automate/006image').expanduser()
file_path = path.joinpath('lena.png')
img = Image.open(file_path)
print(img.size, img.mode, type(img))
# img.show()
img_gray = img.convert('L') # 灰度化
img_gray.save(path.joinpath('006image_pillow_gray.png'))
img_sharp = img.filter( ImageFilter.SHARPEN ) # 锐化
img_sharp.save(path.joinpath('006image_pillow_sharp.png'))
scikit-image基本使用
import pathlib
from skimage import io, color
from skimage.filters import unsharp_mask
path = pathlib.Path('~/dev/python/python1024/data/automate/006image').expanduser()
file_path = path.joinpath('lena.png')
img = io.imread(file_path)
print(img.shape, type(img))
# io.imshow(img) # 使用matplotlib显示图像
img_gray = color.rgb2gray(img)
io.imsave(path.joinpath('006image_skimage_gray.png'),img_gray)
# enhanced image = original + amount * (original - blurred)
img_sharp = unsharp_mask(img, radius=20, amount=1)
io.imsave(path.joinpath('006image_skimage_sharp.png'),img_sharp)
opencv基本使用
import pathlib
import cv2
import numpy as np
path = pathlib.Path('~/dev/python/python1024/data/automate/006image').expanduser()
file_path = path.joinpath('lena.png')
img = cv2.imread(str(file_path))
print(img.shape, type(img))
# cv2.imshow('image',img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰化
cv2.imwrite(str(path.joinpath('006image_cv2_gray.png')),img_gray)
kernel = np.array([[-1,-1,-1],
                   [-1, 9,-1],
                   [-1,-1,-1]])
img_sharp = cv2.filter2D(img, -1, kernel) # 锐化
cv2.imwrite(str(path.joinpath('006image_cv2_sharp.png')),img_sharp)

可以看到,pillow 的使用门槛最低,代码也最容易读懂;scikit-imagenumpy无缝结合,图片读取出来的就是一个numpy.ndarray对象;opencv读取出的也是numpy.ndarray,但色彩模式是BGR模式,需要用cvtColor函数进行模式转化。

三个模块间数据互转

当我们用pillow处理图像到一半时,如果需要用到opencv内置的算法,怎么办?

不用重新用opencv再处理一遍,直接把pillow数据转为opencv的即可。

import pathlib
from PIL import Image
import numpy
import cv2
from skimage import io, img_as_float, img_as_ubyte
path = pathlib.Path('~/dev/python/python1024/data/automate/006image').expanduser()
file_path = path.joinpath('lena.png')
img = Image.open(file_path)
# PIL 转 opencv
img_cv = cv2.cvtColor(numpy.asarray(img),cv2.COLOR_RGB2BGR)
print(img_cv.shape)
# opencv 转 PIL
img_back = Image.fromarray(cv2.cvtColor(img_cv,cv2.COLOR_BGR2RGB))
# opencv 转 skimage
img_sk = img_as_float(cv2.cvtColor(img_cv,cv2.COLOR_BGR2RGB))
print(img_sk.shape)
# skimage 转 opencv
img_cv_back = cv2.cvtColor(img_as_ubyte(img_sk),cv2.COLOR_RGB2BGR)
# skimage 转 PIL
img_sk2pil = Image.fromarray(img_as_ubyte(img_sk))
# PIL 转 skimage
img_pil2sk = img_as_float(img_sk2pil)
print(img_sk.s
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值