Python进行图像处理的入门指南
前言
大家好,最近我在学习 Python 图像处理。相比纯算法理论,图像处理最有意思的地方是:代码运行之后马上就能看到效果,一张图片经过裁剪、缩放、灰度化、滤波、边缘检测之后,变化非常直观。
这篇文章面向 Python 初学者,按照“基础概念 → 环境搭建 → 常用操作 → 实战案例 → 完整代码”的路线,带大家从零开始完成一次 Python 图像处理入门实践。
本文主要使用两个常见库:
Pillow:适合图片打开、保存、缩放、裁剪、格式转换等基础处理OpenCV:适合图像增强、滤波、边缘检测、轮廓识别等计算机视觉任务
一、图像处理基础
1.1 什么是图像处理
图像处理就是使用程序对图片进行读取、分析、修改和保存。常见任务包括:
- 图片格式转换:例如 PNG 转 JPG
- 图片尺寸调整:例如生成缩略图
- 图片裁剪:截取指定区域
- 灰度处理:把彩色 图转换为黑白图
- 图像增强:调整亮度、对比度、锐化
- 边缘检测:提取物体轮廓
- 批量处理:一次性处理多个图片文件
1.2 图像在程序中的表示
一张图片在计算机里本质上是像素矩阵。
彩色 图片通常由三个通道组成:
- R:红色通道
- G:绿色通道
- B:蓝色通道
在 OpenCV 中,默认通道顺序是 BGR,不是常见的 RGB,这是初学者非常容易踩坑的地方。
import cv2
image = cv2.imread("demo.jpg")
print(image.shape)
如果输出:
(600, 800, 3)
表示图片高度为 600,宽度为 800,有 3 个颜色通道。
二、环境搭建
2.1 安装依赖库
在命令提示符或 PowerShell 中执行:
pip install pillow opencv-python numpy matplotlib
各库作用如下:
pillow:基础图像读写和处理opencv-python:计算机视觉处理numpy:矩阵计算matplotlib:显示图片和绘图
2.2 准备测试图片
建议准备一张普通图片,例如:
demo.jpg
把图片和 Python 脚本放在同一个文件夹中,方便后续读取。
目录结构可以这样:
image_demo/ ├── demo.jpg └── image_processing_demo.py
三、使用 Pillow 进行基础操作
3.1 打开和保存图片
from PIL import Image
image = Image.open("demo.jpg")
print(image.size)
print(image.mode)
image.save("output_copy.jpg")
说明:
image.size:图片尺寸,返回(宽度, 高度)image.mode:图片模式,例如RGB、RGBA、Lsave():保存图片
3.2 图片缩放
from PIL import Image
image = Image.open("demo.jpg")
resized = image.resize((400, 300))
resized.save("output_resized.jpg")
如果想按比例缩放,可以这样写:
from PIL import Image
image = Image.open("demo.jpg")
width, height = image.size
new_width = 400
new_height = int(height * new_width / width)
resized = image.resize((new_width, new_height))
resized.save("output_keep_ratio.jpg")
3.3 图片裁剪
from PIL import Image
image = Image.open("demo.jpg")
box = (100, 100, 500, 400)
cropped = image.crop(box)
cropped.save("output_cropped.jpg")
crop() 的参数是一个四元组:
(左, 上, 右, 下)
3.4 灰度转换
from PIL import Image
image = Image.open("demo.jpg")
gray = image.convert("L")
gray.save("output_gray.jpg")
L 表示灰度模式,每个像素只保留亮度信息。
四、使用 OpenCV 进行图像处理
4.1 读取和显示图片
import cv2
image = cv2.imread("demo.jpg")
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:
cv2.imread()读取图片cv2.imshow()显示图片cv2.waitKey(0)等待键盘输入cv2.destroyAllWindows()关闭窗口
4.2 BGR 转 RGB
OpenCV 默认使用 BGR。如果要用 matplotlib 显示,需要转换为 RGB。
import cv2
import matplotlib.pyplot as plt
image = cv2.imread("demo.jpg")
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(rgb_image)
plt.axis("off")
plt.show()
4.3 灰度图
import cv2
image = cv2.imread("demo.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imwrite("opencv_gray.jpg", gray)
4.4 高斯模糊
高斯模糊常用于降噪,让图片变得更平滑。
import cv2
image = cv2.imread("demo.jpg")
blurred = cv2.GaussianBlur(image, (7, 7), 0)
cv2.imwrite("opencv_blur.jpg", blurred)
参数 (7, 7) 是卷积核大小,必须是正奇数。
4.5 边缘检测
Canny 边缘检测可以提取图片中的轮廓线。
import cv2
image = cv2.imread("demo.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
cv2.imwrite("opencv_edges.jpg", edges)
其中 100 和 200 是两个阈值,阈值不同,边缘检测结果也会不同。
五、实战项目一:批量生成缩略图
很多网站或后台系统都需要生成缩略图。下面用 Pillow 批量处理一个文件夹中的图片。
from pathlib import Path
from PIL import Image
def create_thumbnails(input_dir, output_dir, size=(300, 300)):
input_path = Path(input_dir)
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
image_exts = [".jpg", ".jpeg", ".png", ".bmp"]
for file_path in input_path.iterdir():
if file_path.suffix.lower() not in image_exts:
continue
image = Image.open(file_path)
image.thumbnail(size)
save_path = output_path / f"{file_path.stem}_thumb.jpg"
image.convert("RGB").save(save_path, quality=90)
print(f"已生成缩略图:{save_path}")
create_thumbnails("images", "thumbnails")
thumbnail() 会保持原始比例,不会强行拉伸图片。
六、实战项目二:批量添加文字水印
在图片右下角添加文字水印,是非常常见的批处理需求。
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
def add_text_watermark(image_path, output_path, text):
image = Image.open(image_path).convert("RGBA")
watermark_layer = Image.new("RGBA", image.size, (255, 255, 255, 0))
draw = ImageDraw.Draw(watermark_layer)
font = ImageFont.truetype("arial.ttf", 32)
text_box = draw.textbbox((0, 0), text, font=font)
text_width = text_box[2] - text_box[0]
text_height = text_box[3] - text_box[1]
x = image.width - text_width - 30
y = image.height - text_height - 30
draw.text((x, y), text, font=font, fill=(255, 255, 255, 160))
result = Image.alpha_composite(image, watermark_layer)
result.convert("RGB").save(output_path, quality=95)
def batch_add_watermark(input_dir, output_dir, text):
input_path = Path(input_dir)
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
for file_path in input_path.glob("*.*"):
if file_path.suffix.lower() not in [".jpg", ".jpeg", ".png"]:
continue
save_path = output_path / f"{file_path.stem}_watermark.jpg"
add_text_watermark(file_path, save_path, text)
print(f"已添加水印:{save_path}")
batch_add_watermark("images", "watermarked", "Python Image")
如果 arial.ttf 找不到,可以换成 Windows 常见字体路径:
font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 32)
七、实战项目三:图像边缘检测工具
下面做一个完整的小工具:读取图片、灰度化、模糊降噪、边缘检测,并把每一步结果保存下来。
from pathlib import Path
import cv2
def detect_edges(image_path, output_dir):
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
image = cv2.imread(str(image_path))
if image is None:
raise FileNotFoundError(f"图片读取失败:{image_path}")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 80, 180)
cv2.imwrite(str(output_path / "01_gray.jpg"), gray)
cv2.imwrite(str(output_path / "02_blurred.jpg"), blurred)
cv2.imwrite(str(output_path / "03_edges.jpg"), edges)
print("处理完成,结果已保存。")
detect_edges("demo.jpg", "edge_output")
这个流程适合用来理解很多视觉任务的前处理步骤。
八、完整代码演示
下面是一份完整代码,整合了图片信息读取、缩放、裁剪、灰度化、模糊、边缘检测、批量缩略图和水印功能。
保存为 image_processing_demo.py:
from pathlib import Path
import cv2
from PIL import Image, ImageDraw, ImageFont
IMAGE_EXTS = [".jpg", ".jpeg", ".png", ".bmp"]
def show_image_info(image_path):
image = Image.open(image_path)
print("图片路径:", image_path)
print("图片尺寸:", image.size)
print("图片模式:", image.mode)
print("图片格式:", image.format)
def resize_keep_ratio(image_path, output_path, new_width=500):
image = Image.open(image_path)
width, height = image.size
new_height = int(height * new_width / width)
resized = image.resize((new_width, new_height))
resized.save(output_path)
def crop_center(image_path, output_path, crop_width=400, crop_height=300):
image = Image.open(image_path)
width, height = image.size
left = (width - crop_width) // 2
top = (height - crop_height) // 2
right = left + crop_width
bottom = top + crop_height
cropped = image.crop((left, top, right, bottom))
cropped.save(output_path)
def convert_to_gray(image_path, output_path):
image = Image.open(image_path)
gray = image.convert("L")
gray.save(output_path)
def opencv_blur_and_edges(image_path, output_dir):
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
image = cv2.imread(str(image_path))
if image is None:
raise FileNotFoundError(f"图片读取失败:{image_path}")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 80, 180)
cv2.imwrite(str(output_path / "gray.jpg"), gray)
cv2.imwrite(str(output_path / "blurred.jpg"), blurred)
cv2.imwrite(str(output_path / "edges.jpg"), edges)
def create_thumbnails(input_dir, output_dir, size=(300, 300)):
input_path = Path(input_dir)
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
for file_path in input_path.iterdir():
if file_path.suffix.lower() not in IMAGE_EXTS:
continue
image = Image.open(file_path)
image.thumbnail(size)
save_path = output_path / f"{file_path.stem}_thumb.jpg"
image.convert("RGB").save(save_path, quality=90)
print(f"缩略图已保存:{save_path}")
def load_font(size):
font_candidates = [
"C:/Windows/Fonts/msyh.ttc",
"C:/Windows/Fonts/simhei.ttf",
"arial.ttf"
]
for font_path in font_candidates:
if Path(font_path).exists():
return ImageFont.truetype(font_path, size)
return ImageFont.load_default()
def add_text_watermark(image_path, output_path, text):
image = Image.open(image_path).convert("RGBA")
watermark_layer = Image.new("RGBA", image.size, (255, 255, 255, 0))
draw = ImageDraw.Draw(watermark_layer)
font = load_font(32)
text_box = draw.textbbox((0, 0), text, font=font)
text_width = text_box[2] - text_box[0]
text_height = text_box[3] - text_box[1]
x = image.width - text_width - 30
y = image.height - text_height - 30
draw.text((x, y), text, font=font, fill=(255, 255, 255, 160))
result = Image.alpha_composite(image, watermark_layer)
result.convert("RGB").save(output_path, quality=95)
def batch_add_watermark(input_dir, output_dir, text):
input_path = Path(input_dir)
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
for file_path in input_path.iterdir():
if file_path.suffix.lower() not in [".jpg", ".jpeg", ".png"]:
continue
save_path = output_path / f"{file_path.stem}_watermark.jpg"
add_text_watermark(file_path, save_path, text)
print(f"水印图片已保存:{save_path}")
def main():
demo_image = Path("demo.jpg")
if not demo_image.exists():
print("请先在当前目录准备一张 demo.jpg 测试图片。")
return
Path("output").mkdir(exist_ok=True)
show_image_info(demo_image)
resize_keep_ratio(demo_image, "output/resized.jpg", new_width=500)
crop_center(demo_image, "output/cropped.jpg", crop_width=400, crop_height=300)
convert_to_gray(demo_image, "output/gray.jpg")
opencv_blur_and_edges(demo_image, "output/opencv")
add_text_watermark(demo_image, "output/watermark.jpg", "Python Image")
print("基础图像处理完成,结果在 output 文件夹中。")
if Path("images").exists():
create_thumbnails("images", "output/thumbnails")
batch_add_watermark("images", "output/watermarked", "Python Image")
else:
print("如果需要批量处理,请创建 images 文件夹并放入图片。")
if __name__ == "__main__":
main()
九、运行说明
9.1 安装依赖
pip install pillow opencv-python numpy matplotlib
9.2 准备图片
把一张测试图片命名为:
demo.jpg
并和代码文件放在同一个目录。
9.3 运行程序
python image_processing_demo.py
运行后会生成:
output/
├── resized.jpg
├── cropped.jpg
├── gray.jpg
├── watermark.jpg
└── opencv/
├── gray.jpg
├── blurred.jpg
└── edges.jpg如果你创建了 images 文件夹并放入多张图片,程序还会批量生成缩略图和水印图。
十、常见问题与解决方案
10.1 cv2.imread 读取结果是 None
常见原因:
- 图片路径写错
- 文件名不存在
- 路径中包含特殊字符
- 图片文件损坏
建议先用 Path.exists() 判断文件是否存在。
10.2 OpenCV 显示颜色不对
OpenCV 默认是 BGR,matplotlib 默认按 RGB 显示,所以需要转换:
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
10.3 水印中文乱码或不显示
通常是字体不支持中文。Windows 下可以使用:
font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 32)
10.4 保存 JPG 时报错
如果图片是 RGBA 模式,直接保存为 JPG 可能报错,需要先转换为 RGB:
image.convert("RGB").save("output.jpg")
十一、图像处理的应用场景
Python 图像处理可以应用在很多实际场景中:
- 电商图片批量压缩、裁剪、水印
- 证件照背景处理
- 文档扫描件增强
- OCR 文字识别前处理
- 医学影像预处理
- 工业缺陷检测
- 视频帧分析
- 机器学习数据集清洗和增强
如果继续深入,可以学习:
- OpenCV 轮廓检测
- 图像阈值分割
- 形态学操作
- 模板匹配
- 人脸检测
- 图像分类
- 目标检测
十二、总结
Python 图像处理是一个非常适合通过实践学习的方向。入门阶段建议先掌握 Pillow 和 OpenCV 的基础用法:
- 使用 Pillow 完成图片打开、保存、缩放、裁剪、灰度转换和水印
- 使用 OpenCV 完成灰度化、模糊、边缘检测等视觉处理
- 使用 pathlib 管理文件路径
- 把单张图片处理扩展为批量图片处理
从学习路径上看,可以先做小工具,再做完整项目。比如先写一个图片缩放脚本,再扩展成批量压缩工具;先做边缘检测,再扩展成轮廓提取和目标识别。
保持学习,保持输出。图像处理并不是只能停留在理论里,只要多动手写代码,一张普通图片也可以变成很好的练习素材。
以上就是Python进行图像处理的入门指南的详细内容,更多关于Python进行图像处理的资料请关注脚本之家其它相关文章!
相关文章
详解Python中的Numpy、SciPy、MatPlotLib安装与配置
这篇文章主要介绍了详解Python中的Numpy、SciPy、MatPlotLib安装与配置,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-11-11
详解python websocket获取实时数据的几种常见链接方式
这篇文章主要介绍了详解python websocket获取实时数据的几种常见链接方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-07-07


最新评论