用到环境
1、pycharm community edition 2022.3.2
2、Python 3.10
后续应该会在资源上传项目,需要的话可以私信我。
导入 cv2、pytesseract、re 和 locale 模块。
使用 cv2.imread() 函数加载名为 cheque.jpg 的支票图像,然后使用 cv2.cvtColor() 函数将其转换为灰度图像并显示在窗口中。程序会等待用户按下键盘后继续执行。
根据实验一图像增强所学,使用 cv2.equalizeHist() 函数对灰度图像进行直方图均衡化,以提高对比度,增强金额提取效果,并将结果显示在窗口中。程序会等待用户按下键盘后继续执行。
设置 Tesseract 可执行文件的路径,以便后面使用 OCR 引擎识别文本。
OCR (Optical Character Recognition) 的调用通常会使用卷积神经网络(Convolutional Neural Network, CNN)提取输入图像中的字符或文字特征。CNN 模型由多层卷积层、池化层以及全连接层OCR 的调用中有一种常见的技术叫做金字塔模型(Pyramid Model),它可以提高 OCR 的识别率。
OCR技术也运用了金字塔模型。在 OCR 中,金字塔模型通常被用来处理输入图像的不同尺度,以便在不同尺度下检测和识别字符或文字。这是因为在实际应用中,输入图像的大小和分辨率可能会有很大差异,而字符或文字的大小也会有很大变化。如果只在单一尺度下进行 OCR,那么就很难同时兼顾识别准确率和效率。使用金字塔模型可以将输入图像缩小到多个尺度,然后在每个尺度上进行 OCR 处理,最后将结果合并起来得到最终的识别结果。组成,其中卷积层用于提取特征,池化层则用于减小特征图的尺寸和数量。
使用 pytesseract.image_to_string() 函数调用 OCR 引擎(Tesseract)来识别灰度图像中的文本,并将结果存储在变量 text 中。
正则化金额匹配:
分析:直方图均衡化后可以很好的增强图像,使得被提取金额更突出,利于后续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'(?.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!!!