Pillow ImagePalette 模块
下面为你提供 Pillow(PIL Fork)中 ImageStat 模块 的完整入门指南,包含功能介绍、核心方法、代码示例、实际应用场景及高级技巧。
(基于 Pillow ≥ 9.0,Python 3.8+)
1. 安装 Pillow
pip install --upgrade pillow
2. 基本导入
from PIL import Image, ImageStat
3. ImageStat 模块概述
ImageStat.Stat 是一个用于计算图像统计信息的类,支持单通道(灰度)或多通道(RGB/RGBA)图像的像素统计。它可以快速获取:
- 基本统计:最小值、最大值、均值、方差、标准差
- 通道统计:每个通道(R、G、B 或灰度)的独立统计
- 像素计数:总像素数、非零像素计数
- 直方图:像素值分布
适用场景:
- 图像亮度/对比度分析
- 图像质量评估
- 自动调整对比度/亮度
- 图像分割预处理
- 颜色分布分析
4. 核心类:ImageStat.Stat
4.1 初始化
img = Image.open("photo.jpg").convert("RGB")
stat = ImageStat.Stat(img)
参数:
image:PIL 图像对象(支持L,RGB,RGBA等模式)mask(可选):灰度蒙版,仅统计蒙版非零区域extrema(可选):预计算的(min, max)元组
4.2 可用属性
| 属性 | 说明 | 返回值 |
|---|---|---|
extrema | 每个通道的最小/最大值 | [(min_r, max_r), (min_g, max_g), (min_b, max_b)] |
count | 每个通道的像素总数 | [count_r, count_g, count_b] |
sum | 每个通道像素值总和 | [sum_r, sum_g, sum_b] |
sum2 | 每个通道像素值平方和 | [sum2_r, sum2_g, sum2_b] |
mean | 每个通道均值 | [mean_r, mean_g, mean_b] |
median | 每个通道中值 | [median_r, median_g, median_b] |
rms | 均方根(RMS) | [rms_r, rms_g, rms_b] |
var | 每个通道方差 | [var_r, var_g, var_b] |
stddev | 每个通道标准差 | [stddev_r, stddev_g, stddev_b] |
5. 基础用法示例
5.1 获取亮度均值(灰度图)
img = Image.open("photo.jpg").convert("L") # 转灰度
stat = ImageStat.Stat(img)
print(f"亮度均值: {stat.mean[0]:.2f}")
print(f"亮度标准差: {stat.stddev[0]:.2f}")
5.2 RGB 通道统计
img = Image.open("photo.jpg").convert("RGB")
stat = ImageStat.Stat(img)
print(f"RGB 均值: R={stat.mean[0]:.2f}, G={stat.mean[1]:.2f}, B={stat.mean[2]:.2f}")
print(f"RGB 范围: {stat.extrema}")
5.3 使用蒙版统计局部区域
from PIL import ImageDraw
img = Image.open("photo.jpg").convert("RGB")
mask = Image.new("L", img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((100, 100, 300, 300), fill=255) # 圆形区域
stat = ImageStat.Stat(img, mask=mask)
print(f"圆形区域 RGB 均值: {stat.mean}")
6. 实际应用场景
6.1 自动亮度调整(基于均值)
def auto_brightness(img, target_mean=128):
stat = ImageStat.Stat(img.convert("L"))
current_mean = stat.mean[0]
factor = target_mean / current_mean
from PIL import ImageEnhance
return ImageEnhance.Brightness(img).enhance(factor)
img = Image.open("dark.jpg")
adjusted = auto_brightness(img)
adjusted.save("auto_bright.jpg")
6.2 检测图像是否过暗/过亮
def is_image_too_dark_or_bright(img, dark_threshold=50, bright_threshold=200):
stat = ImageStat.Stat(img.convert("L"))
mean = stat.mean[0]
if mean < dark_threshold:
return "太暗"
elif mean > bright_threshold:
return "太亮"
return "正常"
print(is_image_too_dark_or_bright(Image.open("photo.jpg")))
6.3 颜色分布分析(生成调色板)
def extract_palette(img, bins=16):
img = img.convert("RGB").resize((100, 100)) # 缩小加速
stat = ImageStat.Stat(img)
hist = stat.histogram # 获取直方图
palette = []
for i in range(0, 256, 256//bins):
r = g = b = i
palette.append((r, g, b))
return palette
palette = extract_palette(Image.open("flower.jpg"))
print(f"调色板: {palette[:5]}")
7. 高级技巧
7.1 局部统计(人脸区域亮度分析)
def face_brightness(img, face_bbox):
mask = Image.new("L", img.size, 0)
draw = ImageDraw.Draw(mask)
draw.rectangle(face_bbox, fill=255)
stat = ImageStat.Stat(img.convert("L"), mask=mask)
return stat.mean[0]
# 示例:假设人脸区域
bbox = (150, 100, 350, 300)
mean_brightness = face_brightness(Image.open("portrait.jpg"), bbox)
print(f"人脸区域亮度: {mean_brightness:.2f}")
7.2 图像质量评估(标准差)
def assess_image_quality(img):
stat = ImageStat.Stat(img.convert("L"))
stddev = stat.stddev[0]
if stddev < 10:
return "低对比(模糊或单色)"
elif stddev > 50:
return "高对比(清晰或噪点多)"
return "正常"
print(assess_image_quality(Image.open("photo.jpg")))
7.3 批量分析文件夹内图像
import os
def analyze_folder(folder):
results = []
for fname in os.listdir(folder):
if fname.lower().endswith(('.png', '.jpg', '.jpeg')):
img = Image.open(os.path.join(folder, fname)).convert("RGB")
stat = ImageStat.Stat(img)
results.append({
"file": fname,
"mean": [round(m, 2) for m in stat.mean],
"stddev": [round(s, 2) for s in stat.stddev]
})
return results
# 使用
stats = analyze_folder("photos")
for r in stats:
print(f"{r['file']}: 均值={r['mean']}, 标准差={r['stddev']}")
8. 完整示例:自动对比度增强
from PIL import Image, ImageStat, ImageEnhance
def auto_contrast(img):
stat = ImageStat.Stat(img.convert("L"))
min_val, max_val = stat.extrema[0]
if max_val == min_val:
return img # 单色图跳过
# 线性拉伸至 0~255
factor = 255 / (max_val - min_val)
img = ImageEnhance.Contrast(img).enhance(factor)
return img
img = Image.open("low_contrast.jpg")
enhanced = auto_contrast(img)
enhanced.save("auto_contrast.jpg")
9. 性能优化建议
| 场景 | 建议 |
|---|---|
| 大图统计 | 先 resize 缩小(如 100×100) |
| 重复统计 | 缓存 ImageStat.Stat 对象 |
| 局部统计 | 使用 mask 或 crop 限制区域 |
| 直方图分析 | 结合 Image.histogram() |
10. 常见问题 & 解决方案
| 问题 | 原因 | 解决 |
|---|---|---|
mean 返回空 | 图像模式不支持(如 P) | 转换为 L 或 RGB |
| 蒙版无效 | 蒙版不是 L 模式 | mask.convert("L") |
| 计算缓慢 | 图像过大 | 先 resize 或用 numpy 替代 |
| 统计值不准 | 蒙版区域全黑 | 检查蒙版非零像素 |
11. 官方文档
- https://pillow.readthedocs.io/en/stable/reference/ImageStat.html
一键工具脚本:imgstat_tool.py
#!/usr/bin/env python3
import argparse
from PIL import Image, ImageStat
def main():
parser = argparse.ArgumentParser(description="图像统计工具")
parser.add_argument("image", help="输入图像路径")
parser.add_argument("--mode", choices=["L", "RGB"], default="RGB")
parser.add_argument("--bbox", nargs=4, type=int, help="区域统计 (x1 y1 x2 y2)")
args = parser.parse_args()
img = Image.open(args.image).convert(args.mode)
if args.bbox:
img = img.crop(args.bbox)
stat = ImageStat.Stat(img)
print(f"文件名: {args.image}")
print(f"模式: {args.mode}")
print(f"像素总数: {stat.count[0]}")
print(f"均值: {[round(m, 2) for m in stat.mean]}")
print(f"标准差: {[round(s, 2) for s in stat.stddev]}")
print(f"范围: {stat.extrema}")
if __name__ == "__main__":
main()
使用:
python imgstat_tool.py photo.jpg --mode L
python imgstat_tool.py photo.jpg --bbox 100 100 300 300
需要我帮你实现 图像质量自动分级、颜色分布可视化、区域亮度对比、批量统计报表 等功能吗?直接说需求,我给你完整代码!