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


import os
import cv2
import numpy as np


def remove_background_by_contour(square_img):
    """Вырезает фигуру по её контуру, делает фон вокруг фигуры прозрачным."""
    # Переводим в BGRA (с альфа-каналом)
    bgra = cv2.cvtColor(square_img, cv2.COLOR_BGR2BGRA)

    # Переводим в градации серого и сглаживаем шумы
    gray = cv2.cvtColor(square_img, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # Автоматическое определение порогов для Canny
    median_val = np.median(blurred)
    lower_thresh = int(max(0, (1.0 - 0.33) * median_val))
    upper_thresh = int(min(255, (1.0 + 0.33) * median_val))

    # Находим границы (Canny Edge Detection)
    edges = cv2.Canny(blurred, lower_thresh, upper_thresh)

    # Закрываем разрывы в контурах (морфологическое закрытие)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)

    # Находим контуры
    contours, _ = cv2.findContours(
        closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )

    if contours:
        # Создаем маску для выделения фигуры
        mask = np.zeros(gray.shape, dtype=np.uint8)

        # Берем самый крупный контур (это и есть фигура в центре клетки)
        c = max(contours, key=cv2.contourArea)

        # Заполняем область внутри контура белым цветом (255)
        cv2.drawContours(mask, [c], -1, 255, thickness=cv2.FILLED)

        # Сглаживаем края маски, чтобы обрезка была аккуратной
        mask = cv2.GaussianBlur(mask, (3, 3), 0)

        # Применяем маску к альфа-каналу (все, что снаружи маски, станет прозрачным)
        bgra[:, :, 3] = mask
    else:
        # Если контур не найден (например, пустая клетка), делаем полностью прозрачным
        bgra[:, :, 3] = 0

    return bgra


def crop_chess_pieces(image_path, output_dir="templates"):
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    img = cv2.imread(image_path)
    if img is None:
        print("Ошибка: Не удалось загрузить изображение!")
        return

    height, width, _ = img.shape

    # Вычисляем размер клетки (доска 8х8)
    square_h = height / 8.0
    square_w = width / 8.0

    # Строки 0 и 1 — черные фигуры; 6 и 7 — белые фигуры (белые снизу)
    target_rows = [0, 1, 6, 7]

    counter = 1

    for row in target_rows:
        for col in range(8):
            # Координаты клетки
            y1 = int(row * square_h)
            y2 = int((row + 1) * square_h)
            x1 = int(col * square_w)
            x2 = int((col + 1) * square_w)

            # Вырезаем область клетки
            square_crop = img[y1:y2, x1:x2]

            # Вырезаем фон по контуру
            transparent_figure = remove_background_by_contour(square_crop)

            # Формируем название файла: figure_1.png, figure_2.png и т.д.
            filename = f"figure_{counter}.png"
            save_path = os.path.join(output_dir, filename)

            # Сохраняем в PNG
            cv2.imwrite(save_path, transparent_figure)
            print(f"Сохранено: {save_path}")

            counter += 1


if __name__ == "__main__":
    IMAGE_PATH = "chessboard.png"  # Укажите путь к вашему файлу
    crop_chess_pieces(IMAGE_PATH)