图像处理——以支票识别为例

  用到环境
1、pycharm community edition 2022.3.2
2、Python 3.10
后续应该会在资源上传项目,需要的话可以私信我。

流程

在这里插入图片描述

图1 扩展实验“金额识别”流程图

正文

  1. 导入 cv2、pytesseract、re 和 locale 模块。

  2. 使用 cv2.imread() 函数加载名为 cheque.jpg 的支票图像,然后使用 cv2.cvtColor() 函数将其转换为灰度图像并显示在窗口中。程序会等待用户按下键盘后继续执行。

  3. 根据实验一图像增强所学,使用 cv2.equalizeHist() 函数对灰度图像进行直方图均衡化,以提高对比度,增强金额提取效果,并将结果显示在窗口中。程序会等待用户按下键盘后继续执行。

  4. 设置 Tesseract 可执行文件的路径,以便后面使用 OCR 引擎识别文本。
      OCR (Optical Character Recognition) 的调用通常会使用卷积神经网络(Convolutional Neural Network, CNN)提取输入图像中的字符或文字特征。CNN 模型由多层卷积层、池化层以及全连接层OCR 的调用中有一种常见的技术叫做金字塔模型(Pyramid Model),它可以提高 OCR 的识别率。
      OCR技术也运用了金字塔模型。在 OCR 中,金字塔模型通常被用来处理输入图像的不同尺度,以便在不同尺度下检测和识别字符或文字。这是因为在实际应用中,输入图像的大小和分辨率可能会有很大差异,而字符或文字的大小也会有很大变化。如果只在单一尺度下进行 OCR,那么就很难同时兼顾识别准确率和效率。使用金字塔模型可以将输入图像缩小到多个尺度,然后在每个尺度上进行 OCR 处理,最后将结果合并起来得到最终的识别结果。组成,其中卷积层用于提取特征,池化层则用于减小特征图的尺寸和数量。

  5. 使用 pytesseract.image_to_string() 函数调用 OCR 引擎(Tesseract)来识别灰度图像中的文本,并将结果存储在变量 text 中。

  6. 正则化金额匹配:

  • 定义数字词典 numbers 和单位词典 units,用于后面将金额实体中的单词转换成相应的数字。
  • 使用正则表达式 re.search() 在变量 text 中寻找第一个匹配“单词”的字符串,并将其转换为小写并赋值给 amount_text 变量;如果没有找到,则输出 “No amount found.”。
  • 使用 for 循环,将 amount_text 中出现的数字单词替换为相应的阿拉伯数字,并将单位单词替换为相应的因子。替换使用了 re.sub() 函数和正则表达式。
  • 使用 re.search() 函数再次查找 amount_text 中的数字部分,并将其转换为浮点数类型。如果没有找到,则输出 “No amount found.”。
  • 使用 while 循环,查找 amount_text 中的单位单词,并将其转换为因子。每次循环将当前数字与单位相乘,并将相应的单位单词从 amount_text 中删除,直至没有单位单词了。
  • 使用 locale.currency() 函数将 amount_number 转换为格式化的货币字符串。在这个函数中,grouping=True 表示启用千位分隔符,symbol=‘CNY’ 则表示指定货币符号为 CNY。
  • 输出格式化后的货币字符串。

结果展示

在这里插入图片描述

图2 原图

在这里插入图片描述

图3 直方图均衡化后

分析:直方图均衡化后可以很好的增强图像,使得被提取金额更突出,利于后续OCR提取和金额提取。
在这里插入图片描述

图四 金额提取结果

分析:可以发现实验例图识别结果还不错,其原因主要基于三点,一是直接用OCR检测到右标的准确的数字,但是有时这个数字不明显,这时就可以利用中文大写,如图中“壹仟万元整”,或者利用字幕“一千万元”进行金额提取。基于此在算法设计时充分考虑上述三种情况,进行中文与阿拉伯数字的转换,单位如“千万”与阿拉伯数字的转换,取得了不错的效果。
在这里插入图片描述
在这里插入图片描述

图五 其他图片识别结果

分析:发现识别结果很好。

代码:
import cv2
import pytesseract
import re
import locale

# 加载支票图像并将其转换为灰度图像
image = cv2.imread('cheque.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('origin Image', gray)
# 等待用户按下键盘
cv2.waitKey(0)

#
# # 直方图均衡化  提高对比度
# gray = cv2.equalizeHist(gray)
# cv2.imshow('hist Image', gray)
# # 等待用户按下键盘
# cv2.waitKey(0)


# 设置Tesseract可执行文件的路径
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"


# 使用OCR引擎(例如Tesseract)来识别文本
text = pytesseract.image_to_string(gray, lang='eng', config='--psm 6')
print(text)

# 金额匹配

# 设置货币格式
locale.setlocale(locale.LC_ALL, '')

# 数字词典
numbers = {
    'zero': 0,
    'one': 1,
    'two': 2,
    'three': 3,
    'four': 4,
    'five': 5,
    'six': 6,
    'seven': 7,
    'eight': 8,
    'nine': 9,
    'ten': 10,
    'eleven': 11,
    'twelve': 12,
    'thirteen': 13,
    'fourteen': 14,
    'fifteen': 15,
    'sixteen': 16,
    'seventeen': 17,
    'eighteen': 18,
    'nineteen': 19,
    'twenty': 20,
    'thirty': 30,
    'forty': 40,
    'fifty': 50,
    'sixty': 60,
    'seventy': 70,
    'eighty': 80,
    'ninety': 90
}

# 单位词典
units = {
    'hundred': 100,
    'thousand': 1000,
    'million': 1000000,
    'billion': 1000000000
}

# 匹配金额实体
match = re.search(r'\b(\w+\s*)+\b', text)
if match:
    amount_text = match.group().lower()

    # 替换数字单词为阿拉伯数字
    for word, digit in numbers.items():
        amount_text = amount_text.replace(word, str(digit))

    # 替换单位单词为相应的数字
    for unit, factor in units.items():
        pattern1 = r'(?<!\d)one\s+{}\b'.format(unit)
        repl1 = lambda m: str(factor)
        amount_text = re.sub(pattern1, repl1, amount_text)

        pattern2 = r'\b(\d+)\s*{}\b'.format(unit)
        repl2 = lambda m: str(int(m.group(1)) * factor)
        amount_text = re.sub(pattern2, repl2, amount_text)

    # 提取金额数字部分
    match_number = re.search(r'\b\d+(?:\.\d+)?\b', amount_text)
    if match_number:
        amount_number = float(match_number.group())

        # 将数字与单位相乘
        match_unit = re.search(r'(hundred|thousand|million|billion)', amount_text)
        while match_unit:
            factor = units[match_unit.group()]
            amount_number *= factor
            amount_text = re.sub(match_unit.group(), '', amount_text)
            match_unit = re.search(r'(hundred|thousand|million|billion)', amount_text)

        # 输出格式化货币字符串
        formatted_amount = locale.currency(amount_number, grouping=True, symbol='CNY')
        print('Amount:', formatted_amount)
    else:
        print('No amount found.')
else:
    print('No amount found.')

编写不易,求个点赞!!!!!!!
“你是谁?”

“一个看帖子的人。”

“看帖子不点赞啊?”

“你点赞吗?”

“当然点了。”

“我也会点。”

“谁会把经验写在帖子里。”

“写在帖子里的那能叫经验贴?”

“上流!”
cheer!!!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大不怪将军

如果帮助到你,我很开心

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值