Luke commited on
Commit
e651999
·
1 Parent(s): 7336a40

no message

Browse files
IdentifyModel/cardModel.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ def parse_id_card(text, validation_type, entities=None):
3
+ if validation_type == "身分證正面":
4
+ result = {
5
+ "解析全文內容": text,
6
+ "姓名": entities.get('B-PER', '無法解析') if entities else '無法解析',
7
+ "出生年月日": entities.get('B-DATE', '無法解析') if entities else '無法解析',
8
+ "發證日期": entities.get('I-DATE', '無法解析') if entities else '無法解析',
9
+ "統一編號": entities.get('B-NUM', '無法解析') if entities else '無法解析'
10
+ }
11
+ elif validation_type == "身分證反面":
12
+ result = {
13
+ "解析全文內容": text,
14
+ "父": entities.get('B-FATHER', '無法解析') if entities else '無法解析',
15
+ "母": entities.get('B-MOTHER', '無法解析') if entities else '無法解析',
16
+ "配偶": entities.get('B-SPOUSE', '無法解析') if entities else '無法解析',
17
+ "出生地": entities.get('B-LOC', '無法解析') if entities else '無法解析',
18
+ "住址": entities.get('I-LOC', '無法解析') if entities else '無法解析',
19
+ "編號": entities.get('B-ID', '無法解析') if entities else '無法解析'
20
+ }
21
+ else:
22
+ result = {
23
+ "解析全文內容": text,
24
+ }
25
+
26
+ return result
Plan/AiLLM.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pytesseract
3
+ from transformers import AutoTokenizer, AutoModelForTokenClassification, pipeline
4
+ from IdentifyModel.cardModel import parse_id_card
5
+
6
+ # 初始化 Taiwanese BERT 模型
7
+ tokenizer = AutoTokenizer.from_pretrained("ckiplab/bert-base-chinese")
8
+ model = AutoModelForTokenClassification.from_pretrained("ckiplab/bert-base-chinese-ner")
9
+ ner_pipeline = pipeline("ner", model=model, tokenizer=tokenizer)
10
+
11
+
12
+ def llm_recognition(image, validation_type, language):
13
+ text = pytesseract.image_to_string(image, lang=language)
14
+ ner_results = ner_pipeline(text)
15
+ entities = {result['entity']: text[result['start']:result['end']] for result in ner_results}
16
+ return parse_id_card(text, validation_type, entities)
Plan/pytesseractOCR.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import cv2
2
+ import os
3
+ import pytesseract
4
+
5
+ from IdentifyModel.cardModel import parse_id_card
6
+ from Preprocess.preprocessImg import preprocess_image001
7
+
8
+
9
+ def ocr_recognition(image, validation_type, language):
10
+ try:
11
+ preprocessed_image = preprocess_image001(image)
12
+ custom_config = r'--oem 3 --psm 6'
13
+ text = pytesseract.image_to_string(preprocessed_image, lang=language, config=custom_config)
14
+ return parse_id_card(text, validation_type)
15
+ except Exception as e:
16
+ return str(e)
17
+
18
+ # def ocr_recognition_2(image: str, lang: str = 'chi_tra') -> str:
19
+ # try:
20
+ # img = cv2.imread(image)
21
+ # gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
22
+ # threshold_img = cv2.threshold(gray, 127, 255, cv2.THRESH_TOZERO)[1]
23
+ # result = pytesseract.image_to_string(threshold_img, lang=lang)
24
+ # os.remove(image)
25
+ # return result
26
+ # except Exception as e:
27
+ # return str(e)
Preprocess/preprocessImg.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ from PIL import Image, ImageEnhance
4
+
5
+
6
+ # 方案一
7
+ def preprocess_image001(image):
8
+ # 將影像轉換為 NumPy 數組
9
+ image = np.array(image)
10
+ # 轉為灰階影像
11
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
12
+ # 調整對比度
13
+ enhancer = ImageEnhance.Contrast(Image.fromarray(gray))
14
+ enhanced_image = enhancer.enhance(2)
15
+ # 二值化
16
+ _, binary = cv2.threshold(np.array(enhanced_image), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
17
+ # 去雜訊
18
+ denoised = cv2.fastNlMeansDenoising(binary, None, 30, 7, 21)
19
+ return Image.fromarray(denoised)
app.py CHANGED
@@ -1,13 +1,15 @@
1
- from PIL import Image
2
- import pytesseract
3
- import gradio as gr
4
  import os
 
 
 
 
 
 
 
5
  langs = []
6
 
7
  choices = os.popen('tesseract --list-langs').read().split('\n')[1:-1]
8
 
9
- blocks = gr.Blocks()
10
-
11
 
12
  # If you don't have tesseract executable in your PATH, include the following:
13
  # pytesseract.pytesseract.tesseract_cmd = r'<full_path_to_your_tesseract_executable>'
@@ -29,24 +31,49 @@ blocks = gr.Blocks()
29
  # print(pytesseract.image_to_osd(Image.open('test.png'))
30
 
31
 
32
- def run(image, lang=None):
33
- result = pytesseract.image_to_string(
34
- image, lang=None if lang == [] else lang)
35
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
 
38
  with gr.Blocks() as demo:
39
- gr.Markdown("## Hello pytesseract!")
40
  with gr.Row():
41
- with gr.Column():
42
- image_in = gr.Image(type="pil")
43
- lang = gr.Dropdown(choices)
44
- btn = gr.Button("Run")
45
- with gr.Column():
46
- text_out = gr.TextArea()
47
-
48
- examples = gr.Examples([["./eurotext.png", None]], fn=run, inputs=[
49
- image_in, lang], outputs=[text_out], cache_examples=False)
50
- btn.click(fn=run, inputs=[image_in, lang], outputs=[text_out])
51
-
52
- demo.launch()
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+
3
+ import gradio as gr
4
+
5
+ from Plan.AiLLM import llm_recognition
6
+ from Plan.pytesseractOCR import ocr_recognition
7
+ from Preprocess.preprocessImg import preprocess_image001
8
+
9
  langs = []
10
 
11
  choices = os.popen('tesseract --list-langs').read().split('\n')[1:-1]
12
 
 
 
13
 
14
  # If you don't have tesseract executable in your PATH, include the following:
15
  # pytesseract.pytesseract.tesseract_cmd = r'<full_path_to_your_tesseract_executable>'
 
31
  # print(pytesseract.image_to_osd(Image.open('test.png'))
32
 
33
 
34
+ # 取得所有語言清單
35
+ languages = os.popen('tesseract --list-langs').read().split('\n')[1:-1]
36
+
37
+
38
+ print(' ======================================================== ')
39
+ print(' ###### choices:' + choices)
40
+ print(' ###### GET ENV - TESSDATA_PREFIX:' + os.getenv('TESSDATA_PREFIX'))
41
+ print(' ###### OS - TESSDATA_PREFIX:' + os.environ['TESSDATA_PREFIX'])
42
+ # os.environ['TESSDATA_PREFIX'] = os.getenv('TESSDATA_PREFIX')
43
+ print(' ###### Tesseract_Cmd:' + pytesseract.pytesseract.tesseract_cmd)
44
+ # pytesseract.pytesseract.tesseract_cmd = os.getenv('TESSDATA_PREFIX')
45
+ print(' ======================================================== ')
46
+
47
+
48
+ def preprocess_and_ocr(image, validation_type, language):
49
+ preprocessed_image = preprocess_image001(image)
50
+ ocr_result = ocr_recognition(preprocessed_image, validation_type, language)
51
+ return preprocessed_image, ocr_result
52
+
53
+
54
+ def preprocess_and_llm(image, validation_type, language):
55
+ preprocessed_image = preprocess_image001(image)
56
+ llm_result = llm_recognition(preprocessed_image, validation_type, language)
57
+ return preprocessed_image, llm_result
58
 
59
 
60
  with gr.Blocks() as demo:
 
61
  with gr.Row():
62
+ image_input = gr.Image(type="pil", label="上傳圖片")
63
+ validation_type = gr.Dropdown(choices=["身分證正面", "身分證反面"], label="驗證類別")
64
+ language_dropdown = gr.Dropdown(choices=languages, value="chi_tra", label="語言")
65
+
66
+ with gr.Row():
67
+ ocr_button = gr.Button("使用 OCR")
68
+ llm_button = gr.Button("使用 AI LLM")
69
+
70
+ with gr.Row():
71
+ preprocess_output = gr.Image(label="OCR 預處理圖片")
72
+ with gr.Row():
73
+ ocr_output = gr.JSON(label="OCR 解析結果")
74
+ llm_output = gr.JSON(label="AI LLM 解析結果")
75
+
76
+ ocr_button.click(preprocess_and_ocr, inputs=[image_input, validation_type, language_dropdown], outputs=ocr_output)
77
+ llm_button.click(preprocess_and_llm, inputs=[image_input, validation_type, language_dropdown], outputs=llm_output)
78
+
79
+ demo.launch(share=False)
eurotext.png DELETED
Binary file (31.5 kB)
 
requirements.txt CHANGED
@@ -1,2 +1,7 @@
1
  gradio
2
- pytesseract
 
 
 
 
 
 
1
  gradio
2
+ pytesseract
3
+ transformers
4
+ Pillow
5
+ torch
6
+ huggingface-hub
7
+ opencv-python