File size: 3,182 Bytes
9d29c62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import cv2
import numpy as np
import os
from PIL import Image
from google import genai
from google.genai import types

# 1. 讛讙讚专讜转 (砖讬诐 讗转 讛诪驻转讞 讛讞讚砖 砖诇讱!)
client = genai.Client(api_key="AIzaSyA0odvjKCTS-vZsEjMOlsVsJ4iGaYj5jf0")

def process_and_ocr(image_path):
    print(f"\n--- Processing: {image_path} ---")
    
    # 2. OpenCV - 讝讬讛讜讬 砖讜专讜转 讜讞讬转讜讱
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (7,7), 0)
    thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
    
    # 诪讞讘专讬诐 砖讜专讜转 (拽专谞诇 专讞讘)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 5))
    dilate = cv2.dilate(thresh, kernel, iterations=1)
    contours, _ = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # 诪讬讜谉 诪诇诪注诇讛 诇诪讟讛
    contours = sorted(contours, key=lambda c: cv2.boundingRect(c)[1])
    
    crops = []
    max_w = 0
    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        if w > 60 and h > 20:
            crop = img[y:y+h, x:x+w]
            crops.append(crop)
            if w > max_w: max_w = w

    # 3. Stitching - 讛讚讘拽转 讛讞讬转讜讻讬诐 诇住讟专讬驻 讗讞讚 (诪谞拽讛 砖讟讞讬诐 诇讘谞讬诐)
    # 诪讜住讬驻讬诐 驻讚讬谞讙 砖讬讛讬讛 专讜讞讘 讗讞讬讚 诇讛讚讘拽讛
    final_crops = []
    for c in crops:
        h, w, _ = c.shape
        padded = cv2.copyMakeBorder(c, 5, 5, 0, max_w - w, cv2.BORDER_CONSTANT, value=[255, 255, 255])
        final_crops.append(padded)
    
    if not final_crops:
        print("Error: No text blocks found!")
        return

    # 讛讚讘拽讛 讗谞讻讬转
    stitched_strip = cv2.vconcat(final_crops)
    strip_name = f"strip_{image_path}"
    cv2.imwrite(strip_name, stitched_strip)
    print(f"Stitched strip saved as {strip_name}")

    # 4. 砖诇讬讞讛 诇-Gemini Flash
    pil_img = Image.open(strip_name)
    
    prompt = """
    讛转诪讜谞讛 讛诪爪讜专驻转 讛讬讗 "住讟专讬驻" 讛诪讜专讻讘 诪讞讬转讜讻讬诐 砖诇 砖讗诇转 讘讙专讜转 讘诪转诪讟讬拽讛.
    讛诪砖讬诪讛 砖诇讱: 讞诇抓 讗转 讻诇 讛讟拽住讟 讜讛诪砖讜讜讗讜转 讘讚讬讜拽 诪讜砖诇诐 砖诇 100%.
    讞讜拽讬诐:
    1. 拽专讗 讗转 讛注讘专讬转 讜讛诪转诪讟讬拽讛 讘专爪祝 诪诇诪注诇讛 诇诪讟讛.
    2. 砖讬诐 诇讘 诇驻专讟讬诐 讛拽讟谞讬诐 讘讬讜转专: 砖讘专讬诐, 讞讝拽讜转, e, ln, 讜住讬诪谞讬 诪讬谞讜住.
    3. 讛讞讝专 LaTeX 转拽谞讬 诇讻诇 讛诪转诪讟讬拽讛 讜注讘专讬转 谞拽讬讬讛.
    4. 讛讞讝专 专拽 讗转 讛讟拽住讟 讛诪讞讜诇抓.
    """

    response = client.models.generate_content(
        model='gemini-2.0-flash',
        contents=[pil_img, prompt],
        config=types.GenerateContentConfig(temperature=0.0, max_output_tokens=4096)
    )
    
    print("\n--- OCR RESULT ---")
    print(response.text)
    print("------------------")

# 讛专爪转 讛谞讬住讜讬 注诇 3 讛拽讘爪讬诐 (砖谞讛 讗转 讛砖诪讜转 讗诐 爪专讬讱)
test_files = ["hardest_1.jpg", "ocr_only.jpeg", "simple.jpg"]
for file in test_files:
    if os.path.exists(file):
        process_and_ocr(file)
    else:
        print(f"File {file} not found, skipping...")