如何以表格形式提取发票数据

5

我正试图使用计算机视觉从pdf / image发票中提取数据。为此,我使用了基于OCR的pytesseract。

这是示例发票 enter image description here 你可以在下面找到相同的代码

import pytesseract


img = Image.open("invoice-sample.jpg")

text = pytesseract.image_to_string(img)

print(text)

通过使用pytesseract,我获得了以下输出。
http://mrsinvoice.com

 

’ Invoice

Your Company LLC Address 123, State, My Country P 111-222-333, F 111-222-334


BILLTO:

fofin Oe Invoice # 00001

Alpha Bravo Road 33 Invoice Date 32/12/2001

P: 111-292-333, F: 111-222-334

client@example.net Nomecof Reps Bob
Contact Phone 101-102-103

SHIPPING TO:

eine ce Payment Terms ash on Delivery

Office Road 38
P: 111-333-222, F: 122-222-334 Amount Due: $4,170
office@example.net

NO PRODUCTS / SERVICE QUANTITY / RATE / UNIT AMOUNT
HOURS: PRICE

1 tye 2 $20 $40

2__| Steering Wheel 5 $10 $50

3 | Engine oil 10 $15 $150

4 | Brake Pad 24 $1000 $2,400

Subtotal $275

Tax (10%) $27.5

Grand Total $202.5

‘THANK YOU FOR YOUR BUSINESS

但问题在于我想提取文本,并将其分成不同的部分,如供应商名称、发票号码、项目名称和项目数量。 期望输出
{'date': (2014, 6, 4), 'invoice_number': 'EUVINS1-OF5-DE-120725895', 'amount': 35.24, 'desc': 'Invoice EUVINS1-OF5-DE-120725895 from Amazon EU'}

我也尝试过invoice2data Python库,但它也有很多限制。我还尝试使用正则表达式和OpenCV的Canny边缘检测来分别检测文本框,但未能实现预期的结果。
请问您能帮助我吗?

2
图片格式是标准的吗?表格、名称等是否会出现在附带样本中相同的位置? - ZdaR
不,没有标准格式,因为不同的产品销售商有不同的发票格式。但是,如果你所说的是可能的,那么它也可以工作。 - Mayur Satav
我认为你应该使用Google Vision API,而不是tesseract。Google Vision API将返回各种段落的边界框以及OCR文本,然后您可以构建一些正则表达式来检测地址块、姓名块或表格数据等。 - ZdaR
2
如果没有格式,正则表达式有什么用处?使用正则表达式难道不是硬编码吗?您能否建议一些与机器学习相关的东西? - paradocslover
@MayurSatav - 我遇到了和你一样的问题,你有没有找到解决方案?请建议,我已经检查过但是没有找到相关的解决方案。 - Manz
2个回答

4

你需要进行更多的处理,特别是因为“账单收件人”和“送货收件人”与发票表格不对齐。但是,你可以使用以下代码作为基础。

import cv2
import pytesseract
from pytesseract import Output
import pandas as pd

img = cv2.imread("aF0Dc.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

custom_config = r'-l eng --oem 1 --psm 6 '
d = pytesseract.image_to_data(thresh, config=custom_config, output_type=Output.DICT)
df = pd.DataFrame(d)

df1 = df[(df.conf != '-1') & (df.text != ' ') & (df.text != '')]
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)

sorted_blocks = df1.groupby('block_num').first().sort_values('top').index.tolist()
for block in sorted_blocks:
    curr = df1[df1['block_num'] == block]
    sel = curr[curr.text.str.len() > 3]
    # sel = curr
    char_w = (sel.width / sel.text.str.len()).mean()
    prev_par, prev_line, prev_left = 0, 0, 0
    text = ''
    for ix, ln in curr.iterrows():
        # add new line when necessary
        if prev_par != ln['par_num']:
            text += '\n'
            prev_par = ln['par_num']
            prev_line = ln['line_num']
            prev_left = 0
        elif prev_line != ln['line_num']:
            text += '\n'
            prev_line = ln['line_num']
            prev_left = 0

        added = 0  # num of spaces that should be added
        if ln['left'] / char_w > prev_left + 1:
            added = int((ln['left']) / char_w) - prev_left
            text += ' ' * added
        text += ln['text'] + ' '
        prev_left += len(ln['text']) + added + 1
    text += '\n'
    print(text)

结果

                                                                                             bhttps//mrsinvoice.com 
                                                                                                  Lp 
                  I                                                                              | 
        Your Company LLC Address 123, State, My Country P 111-222-333, F 111-222-334 
        BILL TO: 
        P: 111-222-333, F: 111-222-334                          m                              . 
        dlent@ccomplent 
                                                          Contact Phone                  101-102-103 
        john Doe office                                   ayment  Terms                  ash on Delivery 
        Office Road 38 
        P: 111-833-222, F: 122-222-334                            Amount     Due:   $4,170 
        office@example.net 
          NO  PRODUCTS  / SERVICE                                   QUANTITY  /   RATE / UNIT       AMOUNT 
                                                                        HOURS,         PRICE 
         1  | tyre                                                           2           $20             $40 
         2  | Steering Wheet                                                 5          $10              $50 
         3  | Engine ol                                                     40          $15             $150 
         4  | Brake Pad                                                     2a         $1000          $2,400 
                                                                                     Subtotal           $275 
                                                                                    Tax (10%)          $275 
                                                                                  Grand Total         $302.5 
                                            ‘THANK YOU  FOR YOUR BUSINESS 

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接