OCR再構築メモ(砂場)

Last-modified: 2025-12-07 (日) 20:43:52

・OCRをPythonでやるかGoogleレンズAPIにわたすかで再検討中。
・そもそも画像OCRだとどうしても背景の透過がじゃまで変なゼロや1が化けたり改行判定が入ったりで結構ややこしい。
・あと隣の数字を誤認してたまに嘘が出るケースが結構でている。
・某GPTのOCRはなんか妙なハルシネーションを拾ってきてるがあれはどこからの数字だ

OCR構造化処理(Dolnesプロジェクト仕様準拠)

import os
import re
import cv2
import numpy as np
import pandas as pd
from PIL import Image, ImageEnhance, ImageOps
import pytesseract
import zipfile

=== 定数定義 ===
γ領域 Y座標範囲(1~11行目)

gamma_y_ranges = [

   (670, 688), (689, 707), (708, 727), (728, 746), (747, 766),
   (767, 786), (787, 805), (806, 825), (826, 844), (845, 864), (865, 882)

]

γ領域 X座標範囲(1列・2列)

gamma_x_ranges = {

   "●1列": (1480, 1574),
   "●2列": (1768, 1854)

}

出力列順

ordered_cols = (

   ["ファイル名", "名称", "種別", "tag", "ARCHIVE NUMBER", "解説", "詳細解説"] +
   [f"●1列{i}行" for i in range(1, 12)] + [f"●2列{i}行" for i in range(1, 12)] +
   [f"●1列{i}行チェック結果" for i in range(1, 12)] + [f"●2列{i}行チェック結果" for i in range(1, 12)]

)

=== 関数定義 ===

def ocr_gamma_cell(image, x1, x2, y1, y2):

   region = image.crop((x1, y1, x2, y2)).convert("L")
   region_np = np.array(region)
   _, binarized = cv2.threshold(region_np, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
   white_ratio = np.sum(binarized == 255) / binarized.size
   if white_ratio < 0.5:
       binarized = 255 - binarized  # 黒背景と判定し反転
   pil_bin = Image.fromarray(binarized)
   result = pytesseract.image_to_string(pil_bin, config="--psm 6", lang="eng").strip()
   if re.search(r"[A-Za-z]", result):
       result_retry = pytesseract.image_to_string(
           pil_bin, config="-c tessedit_char_whitelist=0123456789 --psm 6", lang="eng"
       ).strip()
       return result_retry if result_retry else "", "Yes" if result_retry == "" else "No"
   return result, "No" if result.isdigit() else "Yes"

def process_image_v2(image_path):

   img = Image.open(image_path)
   enhanced = ImageEnhance.Contrast(img).enhance(2.0)
   record = {
       "ファイル名": os.path.basename(image_path),
       "名称": pytesseract.image_to_string(enhanced.crop((1300, 140, 1875, 210)), config="--psm 6", lang="eng").strip(),
       "種別": pytesseract.image_to_string(enhanced.crop((1320, 226, 1600, 250)), config="--psm 6", lang="eng").strip(),
       "tag": pytesseract.image_to_string(enhanced.crop((1320, 251, 1600, 280)), config="--psm 6", lang="eng").strip(),
       "ARCHIVE NUMBER": pytesseract.image_to_string(enhanced.crop((1690, 226, 1875, 250)), config="--psm 6", lang="eng").strip(),
       "解説": "",
       "詳細解説": ""
   }
   for col_prefix, (x1, x2) in gamma_x_ranges.items():
       for idx, (y1, y2) in enumerate(gamma_y_ranges, start=1):
           key = f"{col_prefix}{idx}行"
           check_key = f"{key}チェック結果"
           val, flag = ocr_gamma_cell(enhanced, x1, x2, y1, y2)
           record[key] = val
           record[check_key] = flag
   return record

def process_zip_to_csv(zip_path: str, output_prefix: str, batch_size: int = 8):

   extract_dir = os.path.splitext(zip_path)[0] + "_extracted"
   with zipfile.ZipFile(zip_path, 'r') as zip_ref:
       zip_ref.extractall(extract_dir)
   image_paths = sorted([
       os.path.join(extract_dir, f)
       for f in os.listdir(extract_dir)
       if f.lower().endswith((".png", ".jpg", ".jpeg", ".bmp"))
   ])
   all_records = []
   for path in image_paths:
       all_records.append(process_image_v2(path))
   df = pd.DataFrame(all_records)[ordered_cols]
   output_path = f"{output_prefix}_structured_full_FINAL.csv"
   df.to_csv(output_path, index=False, encoding="shift_jis", errors="replace")
   return output_path

結果1:こちらは構造化に失敗している模様。

AR102 A2 Gladius.
ASSAULT RIFLE
tag: weapon, AR
標準的な性能の突撃銃。
前時代の巨大企業メタメトリア社設計。
ARCHIVE NUMBER: 110 10059
突出した性能はないが、高い汎用性のため、 多くの国で制式装備に採用され、 極めて広範に普
及した。
ヒトと呼ばれた彼らが滅びた後も、 ホドに残された自律工廠で生産が続いている。
通常物理攻擊力
通常熱量攻擊力
2923
単発BP消費
15
0
弹速
7560
有効物理攻擊力
3406
連射性能
1965
有効熱量攻撃力
0
集弾性能
496
貫通力
715
基礎照準時間
84
射程距離
5500
裝填数
25
装填時間
230
重量
90
待機消費EP
100
修理CELL
5500

結果2:構造化が中途だが日本語の読み取り精度が変。
TIs127 G2 Faluracan - UT

  • UTILITY MODULE
    tag: Armor, CF, UT
    熱量耐性高\中量級特技背囊。
    特殊兵装は分解装置。
    DPBPIC変換寸面。
    卫儿力卡の主力航空鎧殼。
    一度大地在離札札、空

    身。
    故に彼女たちは、己の血肉を銃弾に変えて戦う。
    ARCHIVE NUMBER: 31247350
    DP
    5750
    DP消費
    5000
    通常物理耐性
    696
    通常熱量耐性
    2640
    有効物理耐性
    492
    有効熱量耐性
    2496
    浸食許容量
    1496
    崩壊許容量
    1210
    廃熱異常許容量
    1067
    漏血許容量
    1320
    重量
    電子障害許容量
    831
    待機消費EP
    寄生污染許容量
    1760
    修理CELL
    210
    3670
    6200