Загрузка данных
import os
import cv2
import numpy as np
os.makedirs("Template_pieces", exist_ok=True)
def prepare_templates():
if not os.path.exists("Start_board.png"):
return
img = cv2.imread("Start_board.png")
if img is None:
return
h, w = img.shape[:2]
board_setup = [
["r", "n", "b", "q", "k", "b", "n", "r"],
["p", "p", "p", "p", "p", "p", "p", "p"],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["P", "P", "P", "P", "P", "P", "P", "P"],
["R", "N", "B", "Q", "K", "B", "N", "R"]
]
for r in range(8):
for c in range(8):
piece = board_setup[r][c]
if piece:
y1 = int(round(r * h / 8))
y2 = int(round((r + 1) * h / 8))
x1 = int(round(c * w / 8))
x2 = int(round((c + 1) * w / 8))
cell = img[y1:y2, x1:x2]
color_prefix = "white_" if piece.isupper() else "black_"
filename = f"Template_pieces/{color_prefix}{piece.upper()}.png"
if not os.path.exists(filename):
cv2.imwrite(filename, cell)
prepare_templates()
def capture_board():
return cv2.imread("board.png")
def detect_color(cell_img):
gray = cv2.cvtColor(cell_img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
white_pixels = np.sum(thresh == 255)
black_pixels = np.sum(thresh == 0)
return "white" if white_pixels >= black_pixels else "black"
def recognize_fen():
board_img = capture_board()
if board_img is None:
print("Файл board.png не найден!")
return
h, w = board_img.shape[:2]
templates = {}
for filename in os.listdir("Template_pieces"):
if filename.endswith(".png"):
path = os.path.join("Template_pieces", filename)
templ = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
templates[filename.split(".")[0]] = templ
fen_rows = []
ascii_board = []
for r in range(8):
empty_count = 0
row_fen = ""
ascii_row = []
y1 = int(round(r * h / 8))
y2 = int(round((r + 1) * h / 8))
for c in range(8):
x1 = int(round(c * w / 8))
x2 = int(round((c + 1) * w / 8))
cell = board_img[y1:y2, x1:x2]
cell_gray = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY) if len(cell.shape) == 3 else cell
cell_color = detect_color(cell)
best_match = None
best_score = float("inf")
for name, templ in templates.items():
piece_color = "white" if name.startswith("white") else "black"
if piece_color != cell_color:
continue
resized_templ = cv2.resize(templ, (cell_gray.shape[1], cell_gray.shape[0]))
score = cv2.norm(cell_gray, resized_templ, cv2.NORM_L2)
if score < best_score:
best_score = score
best_match = name
if best_match and best_score < 15000:
piece_char = best_match.split("_")[1]
if cell_color == "black":
piece_char = piece_char.lower()
if empty_count > 0:
row_fen += str(empty_count)
empty_count = 0
row_fen += piece_char
ascii_row.append(piece_char)
else:
empty_count += 1
ascii_row.append(".")
if empty_count > 0:
row_fen += str(empty_count)
fen_rows.append(row_fen)
ascii_board.append(ascii_row)
fen = "/".join(fen_rows) + " w - - 0 1"
print("\n--- Распознанная доска ---")
for row in ascii_board:
print(" ".join(row))
print(f"\nFEN: {fen}")
recognize_fen()
input("\nНажмите Enter для выхода...")