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


import os
import cv2
import numpy as np


def check_cell_has_piece(cell_gray, threshold=30.0):
    """Проверяет наличие фигуры в клетке путем анализа контрастности (разброса
    цветов) вдоль центрального креста клетки.
    """
    h, w = cell_gray.shape
    if h < 8 or w < 8:
        return False

    mid_y, mid_x = h // 2, w // 2

    # Отступ от краев клетки (15%), чтобы случайно не захватить внешнюю сетку
    margin_x = int(w * 0.15)
    margin_y = int(h * 0.15)

    # Берем срез пикселей по вертикали и горизонтали (крест)
    row_pixels = cell_gray[mid_y, margin_x : w - margin_x]
    col_pixels = cell_gray[margin_y : h - margin_y, mid_x]

    # Объединяем пиксели креста в один массив
    cross_pixels = np.concatenate([row_pixels, col_pixels])

    # Вычисляем стандартное отклонение (показатель контрастности)
    std_dev = float(np.std(cross_pixels))

    # Если контрастность превышает порог — внутри есть фигура
    return std_dev > threshold


def verify_chessboard_grid(gray_crop):
    """Проверяет наличие сетки 8x8 внутри найденного квадрата."""
    h, w = gray_crop.shape
    if h < 64:
        return False, 0

    edges = cv2.Canny(gray_crop, 40, 120)
    col_sums = np.sum(edges, axis=0)
    row_sums = np.sum(edges, axis=1)

    cell_size = w / 8.0
    score_x = 0
    score_y = 0

    for i in range(1, 8):
        idx = int(round(i * cell_size))
        x_min, x_max = max(0, idx - 2), min(w, idx + 3)
        y_min, y_max = max(0, idx - 2), min(h, idx + 3)

        score_x += np.max(col_sums[x_min:x_max]) if x_max > x_min else 0
        score_y += np.max(row_sums[y_min:y_max]) if y_max > y_min else 0

    total_score = score_x + score_y
    return True, total_score


def find_chessboard_strictly_1to1(input_path="board1.png"):
    """Ищет доску, вырезает её в памяти и возвращает:

    1. board_matrix (8x8) — для logic.py
    2. cropped_board (Image) — вырезанную доску для analysis.py
    """
    img = cv2.imread(input_path)
    if img is None:
        print(f"[Ошибка] Не удалось загрузить {input_path}")
        return None, None

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

    edges = cv2.Canny(gray, 30, 150)
    contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    best_board = None
    max_score = -1

    for cnt in contours:
        x, y, w, h = cv2.boundingRect(cnt)

        if w < 80 or h < 80:
            continue

        aspect_ratio = float(w) / h
        if not (0.98 <= aspect_ratio <= 1.02):
            continue

        size = min(w, h)
        crop = gray[y : y + size, x : x + size]

        is_grid, score = verify_chessboard_grid(crop)

        if is_grid and score > max_score:
            max_score = score
            best_board = (x, y, size)

    if best_board is None:
        print(f"[Ошибка] Квадратная доска 1*1 не найдена в {input_path}")
        return None, None

    bx, by, size = best_board
    cropped_board = img[by : by + size, bx : bx + size]
    cropped_gray = gray[by : by + size, bx : bx + size]

    # Анализируем каждую клетку на наличие фигур
    cell_size = size / 8.0
    board_matrix = []

    for row in range(8):
        row_status = []
        for col in range(8):
            x1 = int(round(col * cell_size))
            y1 = int(round(row * cell_size))
            x2 = int(round((col + 1) * cell_size))
            y2 = int(round((row + 1) * cell_size))

            cell_crop = cropped_gray[y1:y2, x1:x2]
            has_piece = check_cell_has_piece(cell_crop, threshold=30.0)
            row_status.append(has_piece)

        board_matrix.append(row_status)

    # Возвращаем матрицу заполнености и вырезанную картинку доски для analysis.py
    return board_matrix, cropped_board


if __name__ == "__main__":
    input_file = "board1.png"

    if os.path.exists(input_file):
        matrix, board_img = find_chessboard_strictly_1to1(input_file)
        if matrix is not None:
            print("[OK] Доска успешно обработана полностью в памяти!")
            print(f"Размер вырезанного изображения: {board_img.shape}")
            print("Матрица клеток:")
            for row in matrix:
                print(row)
    else:
        print(f"Файл {input_file} не найден.")