import cv2
import numpy as np
def crop_chessboard_from_file(
input_path="board.png", output_path="cropped_board.png"
):
# 1. Загружаем картинку
img = cv2.imread(input_path)
if img is None:
print(f"Ошибка: Не удалось найти или открыть файл '{input_path}'.")
return
# Переводим в оттенки серого
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. Ищем внутренние углы (для доски 8х8 внутренних углов 7х7)
pattern_size = (7, 7)
found, corners = cv2.findChessboardCorners(
gray,
pattern_size,
flags=cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_NORMALIZE_IMAGE,
)
if not found:
print("Шахматная доска на картинке не найдена.")
return
# 3. Уточняем координаты найденных точек
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners_subpix = cv2.cornerSubPix(
gray, corners, (11, 11), (-1, -1), criteria
)
# 4. Вычисляем крайние границы найденных углов
x_coords = corners_subpix[:, 0, 0]
y_coords = corners_subpix[:, 0, 1]
x_min, x_max = int(np.min(x_coords)), int(np.max(x_coords))
y_min, y_max = int(np.min(y_coords)), int(np.max(y_coords))
# Рассчитываем примерный размер одной клетки и добавляем отступ,
# чтобы захватить внешние края доски, а не только внутренние углы
cell_size = (x_max - x_min) / (pattern_size[0] - 1)
margin = int(cell_size)
height, width = img.shape[:2]
x_min = max(0, x_min - margin)
y_min = max(0, y_min - margin)
x_max = min(width, x_max + margin)
y_max = min(height, y_max + margin)
# 5. Вырезаем доску и сохраняем
cropped_img = img[y_min:y_max, x_min:x_max]
cv2.imwrite(output_path, cropped_img)
print(f"Готово! Вырезанная доска сохранена в '{output_path}'.")
# Запуск функции
if __name__ == "__main__":
crop_chessboard_from_file("board.png")