def scan_frame(cell_board, color_database, templates_edges, ALL_PIECES, empty_threshold=12):
board = cv2.resize(cell_board, (400, 400))
board_matrix = []
for row in range(8):
row_pieces = []
for col in range(8):
cell = board[row * 50:(row + 1) * 50, col * 50:(col + 1) * 50]
gray_cell = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY)
# 1. Повышаем чёткость Canny (пороги 50, 150 лучше выделяют зубцы верхушек)
cell_edge = cv2.Canny(gray_cell[7:43, 7:43], 50, 150)
# Проверка на пустую клетку
if np.count_nonzero(cell_edge) < empty_threshold:
row_pieces.append('.')
continue
# 2. Определение цвета (белая / черная)
cell_color_vec = np.array(extract_dominant_piece_color(cell))
brightness = np.mean(cell_color_vec)
is_white_piece = brightness > 110
candidate_pieces = [p for p in ALL_PIECES if p.isupper() == is_white_piece]
best_match, max_score = '.', -999.0
for piece_symbol in candidate_pieces:
if piece_symbol not in templates_edges or piece_symbol not in color_database:
continue
# Сравнение формы Canny
res = cv2.matchTemplate(cell_edge, templates_edges[piece_symbol], cv2.TM_CCOEFF_NORMED)
_, shape_score, _, _ = cv2.minMaxLoc(res)
# Штраф за цвет
tpl_color = np.array(color_database[piece_symbol])
color_dist = np.linalg.norm(cell_color_vec - tpl_color)
score = shape_score - (color_dist / 150.0)
# ДОПОЛНИТЕЛЬНЫЙ ВЕС ДЛЯ ВЕРХНЕЙ ЧАСТИ (Верхушки ладьи, ферзя и слона)
# Сравниваем отдельно самые верхние 12 пикселей
top_cell = cell_edge[:12, :]
top_tpl = templates_edges[piece_symbol][:12, :]
top_res = cv2.matchTemplate(top_cell, top_tpl, cv2.TM_CCOEFF_NORMED)
_, top_score, _, _ = cv2.minMaxLoc(top_res)
# Итоговый балл складывает общую форму + акцент на верхушке
final_score = score + (top_score * 0.3)
if final_score > max_score:
max_score = final_score
best_match = piece_symbol
row_pieces.append(best_match)
board_matrix.append(row_pieces)
# Формирование FEN
fen_rows = []
for r in board_matrix:
empty, row_str = 0, ""
for p in r:
if p == '.': empty += 1
else:
if empty > 0: row_str += str(empty); empty = 0
row_str += p
if empty > 0: row_str += str(empty)
fen_rows.append(row_str)
return board_matrix, "/".join(fen_rows) + " w - - 0 1"