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))