基于OpenCV的发票印刷汉字识别:图像预处理与质量优化问询
发票印刷汉字识别的OpenCV预处理实现
你提到要识别发票图像上的印刷汉字,已经裁剪了目标区域,并且基于BGR原始图做预处理——转灰度、反转图像、去噪,还想结合cv2.connectedComponentsWithStats提升画质,我帮你把这段代码补全整理,同时拆解下关键处理逻辑:
完整预处理代码
import cv2 import numpy as np from matplotlib import pyplot as plt import argparse import os NUM1 = 110 # 连通区域面积阈值,过滤小噪声 NUM2 = 2 # 模糊核大小,用于去噪 def main(): # 构建参数解析器,读取输入图像路径 ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="输入裁剪后发票图像的路径") args = vars(ap.parse_args()) # 读取BGR格式原始图像 image = cv2.imread(args["image"]) if image is None: print(f"无法读取目标图像:{args['image']}") return # 1. 转换为灰度图,减少通道数降低计算量 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 2. 反转图像,让文字变为白色、背景变为黑色,适配OCR工具的输入习惯 inverted = cv2.bitwise_not(gray) # 3. 去除噪声,这里用高斯模糊,若遇椒盐噪声可换成cv2.medianBlur denoised = cv2.GaussianBlur(inverted, (NUM2, NUM2), 0) # 4. 用connectedComponentsWithStats筛选有效区域,过滤小斑点噪声 num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(denoised, connectivity=8) # 创建空白图,只保留面积大于阈值的连通区域(即文字区域) filtered = np.zeros_like(denoised) for i in range(1, num_labels): # 跳过背景标签0 area = stats[i, cv2.CC_STAT_AREA] if area > NUM1: filtered[labels == i] = 255 # 可视化各步骤效果(matplotlib自动转为RGB显示) plt.figure(figsize=(12, 6)) plt.subplot(231), plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), plt.title('原始BGR图像') plt.subplot(232), plt.imshow(gray, cmap='gray'), plt.title('灰度图') plt.subplot(233), plt.imshow(inverted, cmap='gray'), plt.title('反转图像') plt.subplot(234), plt.imshow(denoised, cmap='gray'), plt.title('去噪后图像') plt.subplot(235), plt.imshow(filtered, cmap='gray'), plt.title('连通区域筛选后') plt.show() if __name__ == "__main__": main()
关键步骤说明
- 灰度转换:把多通道BGR图转为单通道灰度图,保留文字明暗信息的同时简化后续计算。
- 图像反转:发票印刷文字通常偏深色,反转后文字为白、背景为黑,更契合大部分OCR模型的输入要求。
- 噪声去除:高斯模糊能平滑细微噪声,你可以根据实际噪声类型替换为中值滤波(针对椒盐噪声)。
- 连通区域筛选:通过
cv2.connectedComponentsWithStats识别所有独立区域,用面积阈值过滤掉细碎噪声斑点,只保留有效文字区域。
使用方式
运行代码时,通过命令行传入裁剪后图像的路径即可:
python invoice_preprocess.py --image ./crop_invoice.jpg
内容的提问来源于stack exchange,提问作者Jiancong
相关产品推荐
相关产品推荐

