| import cv2 |
| import numpy as np |
| from PIL import Image |
| import os |
| import io |
|
|
| def run_atomic_test(image_path): |
| |
| 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) |
| |
| |
| 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]) |
|
|
| |
| pil_img = Image.open(image_path).convert("RGB") |
| pages = [] |
| |
| |
| 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 |
| |
| |
| 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 |
| |
| |
| 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))) |
|
|
| |
| 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) |