Загрузка данных


import cv2

def crop_chess_board(input_img):
    """Находит шахматную доску на кадре и обрезает её до 400x400."""
    img_h, img_w = input_img.shape[:2]
    total_area = img_h * img_w

    gray = cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY)

    thresh = cv2.adaptiveThreshold(
        gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
        cv2.THRESH_BINARY_INV, 11, 2
    )

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

    contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if not contours:
        return cv2.resize(input_img, (400, 400))

    contours = sorted(contours, key=cv2.contourArea, reverse=True)
    best_box = None

    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        area = w * h

        if area < (total_area * 0.03) or area > (total_area * 0.95):
            continue

        aspect_ratio = float(w) / h
        if 0.85 <= aspect_ratio <= 1.15:
            best_box = (x, y, w, h)
            break

    if best_box is None:
        edges = cv2.Canny(gray, 50, 150)
        contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        contours = sorted(contours, key=cv2.contourArea, reverse=True)

        for c in contours:
            x, y, w, h = cv2.boundingRect(c)
            area = w * h
            if (total_area * 0.05) < area < (total_area * 0.90) and (0.85 <= float(w) / h <= 1.15):
                best_box = (x, y, w, h)
                break

    if best_box is None:
        return cv2.resize(input_img, (400, 400))

    x, y, w, h = best_box
    cropped_img = input_img[y:y+h, x:x+w]
    return cv2.resize(cropped_img, (400, 400))