做Python图像处理,绕不开两个库:OpenCV和Pillow。前者是计算机视觉领域的 heavyweight 选手,功能强大、性能彪悍;后者则是Python生态里资历最老的图像库之一,上手简单、接口友好。不少初学者在入门阶段都会纠结:到底该学哪一个?其实这两者并不是替代关系,而是互补关系。理解它们各自的定位和调用方式,比纠结二选一重要得多。本文将从安装开始,带你把两个库的核心调用过一遍,最后再聊聊实际项目中的选型策略。

安装与环境准备
先说安装。两个库都能通过pip直接装,但有一些细节值得注意。OpenCV在pip上的包名不是opencv,而是opencv-python,导入时用的模块名是cv2,这个命名方式经常让新手踩坑。Pillow的包名是Pillow,导入时用PIL,这是因为它继承自早期的Python Imaging Library(PIL),为了保持向后兼容才保留了旧的导入名。
pip install opencv-python pip install Pillow
安装完成后,建议先验证一下版本,确认环境没有问题:
import cv2 from PIL import Image print(cv2.__version__) # 例如输出 4.9.0 print(Image.__version__) # Pillow 版本号
有一个常见的坑需要提醒:如果你在服务器或Docker容器里运行OpenCV,调用cv2.imshow时会报错,因为容器里没有图形界面环境。这种情况可以先检查cv2.imshow是否可用,或者在开发阶段用Pillow保存图片到磁盘再查看效果。另外,OpenCV部分功能依赖numpy,安装opencv-python时会自动带上,无需额外操作。
基础操作:读取、显示与保存
两个库最核心的差异之一体现在颜色通道顺序上。OpenCV读取图像使用的是BGR顺序,而Pillow以及其他绝大多数工具使用的是RGB顺序。如果不做转换就直接混用两个库处理同一张图,颜色会明显不对,红蓝互换。这是初学者最常遇到的坑,务必记住:cv2.imread返回的是BGR格式的numpy数组,需要用cv2.cvtColor(img, cv2.COLOR_BGR2RGB)转换后再交给Pillow处理。
先看OpenCV的基础调用:
import cv2
# 读取图像,第二个参数可选:cv2.IMREAD_COLOR 彩色 / cv2.IMREAD_GRAYSCALE 灰度
img = cv2.imread('photo.jpg', cv2.IMREAD_COLOR)
# 查看尺寸,格式为 (高, 宽, 通道数)
print(img.shape)
# 显示图像
cv2.imshow('window', img)
cv2.waitKey(0) # 等待按键
cv2.destroyAllWindows()
# 保存图像
cv2.imwrite('output.jpg', img)再看Pillow的写法,风格上更偏对象化:
from PIL import Image
# 打开图像
img = Image.open('photo.jpg')
# 查看尺寸,格式为 (宽, 高),注意与OpenCV相反
print(img.size)
# 显示图像,会调用系统默认看图程序
img.show()
# 保存图像,可以通过后缀切换格式
img.save('output.png')注意两者尺寸表示的差异:OpenCV的shape返回(高, 宽, 通道),Pillow的size返回(宽, 高)。顺序刚好相反,写代码时一定要留意,否则裁剪或缩放时很容易出现维度错乱的问题。
常用图像处理操作对比
缩放与裁剪
缩放是最高频的操作之一。OpenCV提供了cv2.resize,支持多种插值算法,处理大批量图片时速度优势明显;Pillow的resize和thumbnail接口更简洁,thumbnail还不会改变原图的宽高比,做缩略图非常方便。
import cv2
from PIL import Image
# OpenCV 缩放
img = cv2.imread('photo.jpg')
resized = cv2.resize(img, (800, 600), interpolation=cv2.INTER_AREA)
# Pillow 缩放
pil_img = Image.open('photo.jpg')
resized_pil = pil_img.resize((800, 600))
# Pillow 生成等比缩略图,直接修改原对象
pil_img.thumbnail((300, 300))灰度转换与滤波
灰度转换在两个库里都是一行代码的事,但滤波方面OpenCV明显更丰富,高斯模糊、中值滤波、双边滤波一应俱全。Pillow也内置了模糊、锐化、边缘增强等滤镜,通过ImageFilter模块调用,日常修图够用。
import cv2
from PIL import Image, ImageFilter
# OpenCV:灰度 + 高斯模糊
img = cv2.imread('photo.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(img, (5, 5), 0)
# Pillow:灰度 + 模糊
pil_img = Image.open('photo.jpg')
gray_pil = pil_img.convert('L')
blurred_pil = pil_img.filter(ImageFilter.GaussianBlur(radius=3))文字与几何绘图
OpenCV的绘图API(rectangle、putText等)常用于目标检测结果的可视化,把检测框画在图上非常直观。但它绘制的中文会显示成乱码问号,因为内置字体不支持中文。Pillow配合ImageDraw和ImageFont可以加载系统中文字体,加水印、生成验证码图片这类任务用Pillow更合适。
from PIL import Image, ImageDraw, ImageFont
img = Image.open('photo.jpg').convert('RGB')
draw = ImageDraw.Draw(img)
# 加载中文字体并绘制文字
font = ImageFont.truetype('msyh.ttc', size=36)
draw.text((50, 50), '你好,图像处理', font=font, fill=(255, 0, 0))
img.save('watermarked.jpg')性能与选型建议
从性能角度看,OpenCV底层由C++实现,配合numpy向量化操作,处理高分辨率大图或视频流时速度远超Pillow。以批量缩放1000张2000万像素的图片为例,OpenCV通常能快出数倍。而Pillow的优势在于轻量,安装包小、依赖少、API直观,对于生成缩略图、格式转换、简单加水印这类任务,几行代码就能搞定,没必要引入庞大的OpenCV。
实际项目中的推荐策略是混合使用:用OpenCV做核心的视觉计算(特征提取、目标检测、视频处理),用Pillow做结果的可视化输出和格式保存。两者之间通过numpy数组无缝衔接,OpenCV的图像本身就是numpy数组,转成Pillow对象只需两行代码:
import cv2
from PIL import Image
img = cv2.imread('photo.jpg')
# BGR 转 RGB 后交给 Pillow
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 反向转换:Pillow 转 OpenCV
import numpy as np
cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)最后总结几条经验:做深度学习数据预处理、人脸识别、视频分析,直接上OpenCV;做网站图片服务、批量格式转换、验证码生成,Pillow更轻便省心;两者混用时时刻记得BGR与RGB的转换,能帮你省掉大半的颜色异常排查时间。把这两个库的调用方式都掌握了,绝大多数Python图像处理场景你都能从容应对。
OpenCVPillowPython图像处理修改时间:2026-09-04 00:08:59