2. 基于灰度直方图的图像质量评估
任务说明
在工业OCR流水线中,图像质量直接决定识别成功率。本案例实现一个基于灰度直方图的图像质量评估工具,输入任意灰度图像,输出其灰度直方图数据、亮度均值、标准差对比度,并依据阈值给出“适合OCR/对比度过低/亮度过暗/亮度过亮”的质量判定,用于在采集端筛选出适合OCR的清晰图像。
核心实现
import numpy as np
import cv2
from collections import Counter
def compute_histogram(gray_img):
"""计算灰度直方图,返回256个bin的计数列表"""
hist = cv2.calcHist([gray_img], [0], None, [256], [0, 256])
return hist.flatten().astype(int)
def assess_image_quality(gray_img, low_contrast_thresh=30, dark_thresh=80, bright_thresh=200):
"""
基于灰度直方图评估图像质量
返回: (hist, metrics_dict, quality_label)
"""
hist = compute_histogram(gray_img)
total_pixels = gray_img.size
# 亮度均值
mean_val = float(np.mean(gray_img))
# 标准差对比度
std_val = float(np.std(gray_img))
# 直方图有效灰度范围(覆盖99%像素)
sorted_vals = np.argsort(hist)[::-1]
cumsum = np.cumsum(np.sort(hist)[::-1])
cutoff = total_pixels * 0.99
n_bins_cover = int(np.searchsorted(cumsum, cutoff) + 1)
used_levels = sorted_vals[:n_bins_cover]
gray_range = int(np.max(used_levels) - np.min(used_levels))
# 质量判定
if std_val < low_contrast_thresh:
label = "对比度过低-不适合OCR"
elif mean_val < dark_thresh:
label = "亮度过暗-不适合OCR"
elif mean_val > bright_thresh:
label = "亮度过亮-不适合OCR"
else:
label = "适合OCR"
metrics = {
"mean": round(mean_val, 2),
"std": round(std_val, 2),
"gray_range": gray_range,
"total_pixels": total_pixels
}
return hist, metrics, label
def load_and_assess(image_path):
"""加载图像并评估,返回直方图、指标和判定结果"""
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError(f"无法读取图像: {image_path}")
hist, metrics, label = assess_image_quality(img)
return hist, metrics, label
# 示例:对单张图像执行评估
if __name__ == "__main__":
# 使用一张示例图像(请替换为实际路径)
hist, metrics, label = load_and_assess("sample_ocr_image.png")
print("质量指标:", metrics)
print("判定结果:", label)
# 直方图前10个灰度级的像素计数
print("直方图前10个bin:", hist[:10].tolist())
关键逻辑说明
代码通过OpenCV读取灰度图,计算256级灰度直方图。亮度用像素均值衡量,对比度用标准差和有效灰度范围双重表征。判定规则为:标准差低于30视为对比度过低;均值低于80视为过暗;均值高于200视为过亮;其余情况判定为适合OCR。阈值可根据实际产线光照条件调整。
落地与验证
依赖安装:
pip install opencv-python numpy
运行方式:将代码保存为quality_assess.py,准备一张包含文字的实际拍摄图像(如产品标签照片),替换代码中的sample_ocr_image.png为实际路径后执行:
python quality_assess.py
验证方法:准备三张测试图——一张正常光照下的清晰文字图、一张过暗图、一张模糊低对比图。分别运行程序,观察输出:
- 清晰图应输出“适合OCR”,且std值通常大于30,mean在80~200之间;
- 过暗图mean应小于80,输出“亮度过暗”;
- 模糊图std应小于30,输出“对比度过低”。
判定标准:程序输出的质量标签与人工目视判断一致,且直方图数据与图像实际灰度分布相符,即验证通过。