File size: 3,301 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
85
86
87
import cv2
import numpy as np
from PIL import Image
import os
import io

def run_atomic_test(image_path):
    # --- ืฉืœื‘ 1: ื–ื™ื”ื•ื™ ืจื™ื‘ื•ืขื™ื (ื”ืงื•ื“ ื”ืžื ืฆื— ืฉืœืš) ---
    if not os.path.exists(image_path):
        print(f"โŒ ืฉื’ื™ืื”: ื”ืชืžื•ื ื” ืœื ื ืžืฆืื” ื‘ื ืชื™ื‘: {image_path}")
        return

    image = cv2.imread(image_path)
    img_h, img_w = image.shape[:2]
    
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.adaptiveThreshold(cv2.GaussianBlur(gray, (7,7), 0), 255, 
                                 cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
    
    # ื”ืงืจื ืœ ื”ืจื—ื‘ ืฉื—ื™ื‘ืจ ืœืš ืืช ื”ืฉื•ืจื•ืช ื‘-debug_boxes
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 10))
    dilate = cv2.dilate(thresh, kernel, iterations=1)
    contours, _ = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    blocks = []
    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        if w > 50 and h > 20:
            blocks.append((x, y, w, h))
    
    # ืžื™ื•ืŸ ื”ื‘ืœื•ืงื™ื ืžืœืžืขืœื” ืœืžื˜ื”
    blocks.sort(key=lambda b: b[1])

    # --- ืฉืœื‘ 2: ื—ื™ืชื•ืš ืื˜ื•ืžื™ (V302.5) ---
    pil_img = Image.open(image_path).convert("RGB")
    pages = []
    
    # ื—ื•ืง 1: Header Lock (ืชื•ืคืก ืืช ื”-f(x) ืชืžื™ื“)
    header_limit = 180
    pages.append(pil_img.crop((0, 0, img_w, header_limit)))
    
    # ื ื™ื”ื•ืœ ืชื•ืจ
    remaining = [b for b in blocks if (b[1] + b[3]) > header_limit]
    
    while remaining:
        curr = remaining.pop(0)
        x, y, w, h = curr
        
        # ื—ื•ืง 2: ืื˜ื•ืžื™ื•ืช ื”ื’ืจืฃ (ืื ื’ื‘ื•ื”, ืžืงื‘ืœ ื“ืฃ ืžืฉืœื•)
        if h > 120:
            y_s = max(0, y - 30)
            # ื—ื•ืง ื”ื’ื ืช ื”ื–ื ื‘: ืื ื–ื” ื”ืื—ืจื•ืŸ, ื—ืชื•ืš ืขื“ ืกื•ืฃ ื”ืงื•ื‘ืฅ
            y_e = img_h if not remaining else min(img_h, y + h + 30)
            pages.append(pil_img.crop((0, y_s, img_w, y_e)))
            remaining = [b for b in remaining if b[1] > (y_e - 10)]
            continue
            
        # ื—ื•ืง 3: ืฆื‘ื™ืจ ื˜ืงืกื˜ (ืงื™ื‘ื•ืฅ ืกืขื™ืคื™ื)
        c_min, c_max = y, y + h
        to_consume = []
        for nb in remaining:
            if nb[3] > 120: break
            if (max(c_max, nb[1]+nb[3]) - c_min) <= 750:
                c_max = max(c_max, nb[1]+nb[3])
                to_consume.append(nb)
            else: break
        
        for r in to_consume: remaining.remove(r)
        
        y_t = max(0, c_min - 25)
        y_b = img_h if not remaining else min(img_h, c_max + 25)
        pages.append(pil_img.crop((0, y_t, img_w, y_b)))

    # --- ืฉืœื‘ 3: ืฉืžื™ืจืช ื”ืชื•ืฆืื•ืช ืœืชื™ืงื™ื™ื” ---
    output_dir = "test_results"
    if not os.path.exists(output_dir): os.makedirs(output_dir)
    
    for i, p in enumerate(pages):
        p.save(f"{output_dir}/slice_{i+1}.jpg")
        print(f"โœ… ื ืฉืžืจ Slice {i+1} ื‘ื’ื•ื‘ื” {p.size[1]}px")
    
    print(f"\n๐Ÿš€ ื”ื‘ื“ื™ืงื” ื”ืกืชื™ื™ืžื”! ื‘ื“ื•ืง ืืช ื”ืชืžื•ื ื•ืช ื‘ืชื™ืงื™ื™ืช: {os.path.abspath(output_dir)}")

if __name__ == "__main__":
    # ื•ื•ื“ื ืฉื”ื ืชื™ื‘ ืœืชืžื•ื ื” ื ื›ื•ืŸ
    target_image = r"C:\Users\dotan\OneDrive\ืชืžื•ื ื•ืช\ื‘ื’ืจื•ืช ื—ื•ืจืฃ 26 .jpg"
    run_atomic_test(target_image)