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) |