象棋图片转FEN字符串详细教程

news/2025/10/11 12:52:26/文章来源:https://www.cnblogs.com/funwithwords/p/19134779

如把下图

a1

转换成:3ak4/7R1/3aCcN2/p7p/6r2/9/Pr1p1n2P/4B1p2/9/2BAKA1R1

模型21K,Intel N100上训练时间0.969秒,识别时间0.957秒。识别率好像是100%

一、安装软件包

apt install python3-scipy python3-pil

二、建目录data, data\0 a A b B c C k K n N p P r R

识别就是分类。每个目录对应一类,存放属于该类的所有图片。

三、收集和预处理数据

百度搜相似图片。运行prepare.py: 

#!/usr/bin/python
from common import *
from pathlib import Pathfn = sys.argv[1]
a = slice(fn)
fn = Path(fn).stem
for i in range(len(a)):cv.imwrite(f'data/{fn}-{i}.png', a[i])exit()from PIL import Image, ImageDraw
img = Image.open(sys.argv[1])
id = ImageDraw.Draw(img)
sz = img.size; S,L,T = size(sz[0], sz[1])
for yy in range(10):for xx in range(9):y = T + yy * Sx = L + xx * Sid.rectangle((x,y,x+S,y+S), outline=(0,255,0,255), width=1)
img.show()
View Code

如何知道square的大小?图片查看器Gwenview和IfranView显示选择区的大小。或者用OpenCV的演示程序squares.py来高射炮打蚊子。

人工标注数据。文件管理器里按图标查看,把比如红车的改名为首字母为R。按大小排序,改名时列表不会来回乱变。

#!/usr/bin/python
from glob import glob
from shutil import moves = 'rnbakcp'; s += s.upper() + '0'for c in s:for p in [c + '*.png', c + '*.jpg']:for f in glob(p): move(f, c)
View Code

四、训练,运行train.py

from common import *
from sklearn.svm import SVC
import pickledata_dir = "data"
features = []; labels = []
for label in os.listdir(data_dir):label_dir = os.path.join(data_dir, label)if not os.path.isdir(label_dir): continuefor img_file in os.listdir(label_dir):img_path = os.path.join(label_dir, img_file)img = cv.imread(img_path)if img is None: continuefeature = extract_features(img)if feature is None: continuefeatures.append(feature)labels.append(label)model = SVC(kernel='rbf', C=10, gamma=0.1)
model.fit(features, labels)
with open("model.pkl", "wb") as f: pickle.dump(model, f)
View Code

五,识别

#!/usr/bin/python
from common import *
import pickleb = [[' '] * 9 for i in range(10)]with open('model.pkl', 'rb') as f: model = pickle.load(f)
a = slice(sys.argv[1])
for i in range(len(a)):f = extract_features(a[i])b[i // 9][i % 9] = model.predict([f])[0]def brd2fen (b):f = ''for y in range(10):n = 0for x in range(9):c = b[y][x]if c == '0': n += 1else:if n: f += str(n)f += c; n = 0if n: f += str(n)if y != 9: f += '/'return fprint(brd2fen(b))
for i in range(10): print(b[i])

鄙人的brd2fen是最长的。:-)

五 common.py

import numpy as np
import cv2 as cv
import pickle
import os
import sysdef size (W, H):S = 68 if W == 640 else 86 # sizeL = (W - 9 * S) // 2 # leftT = (H - 10 * S) // 2 # topreturn S,L,Tdef slice (fn):all = []img = cv.imread(fn); H,W = img.shape[:2]S,L,T = size(W, H)mask = np.zeros((S, S), dtype=bool)HS = S // 2; R = HS - 4 # half S & radiusfor y in range(S):for x in range(S):# 圆形mask. hypotenuse: 斜边if np.hypot(x - HS, y - HS) > R: mask[y, x] = Truefor yy in range(10):for xx in range(9):x = L + xx * S; y = T + yy * Sx2 = min(W, x + S); y2 = min(H, y + S)sl = img[y:y2, x:x2]; sl[mask] = 0all.append(sl)return alldef extract_features (img):gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)_, bin = cv.threshold(gray, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)contours, _ = cv.findContours(bin, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)if len(contours) == 0: return Nonecontour = max(contours, key=cv.contourArea)moments = cv.moments(contour)hu_moments = cv.HuMoments(moments).flatten()# 在阴影或强光条件下,RGB会整体变化,而HSV的色调H和饱和度S相对稳定,更适合颜色识别任务。V是亮度。hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)color_features = np.concatenate([cv.mean(hsv)[:3],cv.meanStdDev(hsv)[1].flatten()])return np.concatenate([hu_moments, color_features])
View Code

 

六 其它

circles.py没有用到,但我辛苦地调了参数,愚蠢地用直径去设置min/max raidus,一并附上。

#!/usr/bin/python
import numpy as np
import cv2 as cv
import sys
import osfn = sys.argv[1]
img = cv.imread(fn); height, width = img.shape[:2]
fn = os.path.basename(fn)circles = cv.HoughCircles(cv.cvtColor(img, cv.COLOR_BGR2GRAY), # 只支持灰度cv.HOUGH_GRADIENT, # 梯度,not 渐变1, # 改成2影响很大60, # Minimum distance between the centers of the detected circlesparam1=150, # 减小可增加检测到的圆数量param2=35, # The smaller it is, the more false circles may be detected.minRadius=30,maxRadius=48
) # 返回shape为(1,n,3)的ndarray
if circles is None: exit()
circles = np.around(circles).astype(int)mask = np.zeros((96,96), dtype=bool)
for y in range(96):for x in range(96):# 以(48,48)为圆心,40为半径的mask. hypotenuse 斜边if np.hypot(x - 48, y - 48) > 40: mask[y, x] = Truefor x,y,r in circles[0]:cv.circle(img, (x, y), r, (0, 255, 0), 2)x1 = max(0, x - r); x2 = min(width, x + r)y1 = max(0, y - r); y2 = min(height, y + r)ps = cv.resize(img[y1:y2, x1:x2], (96,96))ps[mask] = 255#cv.imwrite(f'tmp/{fn}-{x},{y}.png', ps)from PIL import Image
img = Image.fromarray(cv.cvtColor(img, cv.COLOR_BGR2RGB))
img.show()print(f'{circles.shape[1]} pieces')
View Code

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/934730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理在风险识别中的应用

本文介绍了如何利用自然语言处理和机器学习技术来识别和预测风险,包括在在线教育平台和产品开发阶段的应用,以及相关技术架构和团队构成。利用自然语言处理理解和识别风险 作为某中心的应用科学经理,Muthu Chandras…

详细介绍:正点原子【第四期】Linux之驱动开发学习笔记-6.1 pinctrl和gpio子系统

详细介绍:正点原子【第四期】Linux之驱动开发学习笔记-6.1 pinctrl和gpio子系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

cat

基本概述 cat命令来自英文词组”concatenate files and print“的缩写,其功能是用于在终端设备上显示文件内容。在Linux系统中有很多用于查看文件内容的命令,例如more、tail、head等,每个命令都有各自的特点。cat命…

深入解析:可持续金融的新范式:拆解欧盟ESG监管体系及其全球影响力

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Docker和K8S的区别详解 - 指南

Docker和K8S的区别详解 - 指南2025-10-11 12:39 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importan…

qt everywhere souce code编译 - 实践

qt everywhere souce code编译 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

2023 CCPC final G

G. China Convex Polygon Contest 反悔贪心。 首先可以考虑对 \(b\) 排序,显然思考越快的题可以使手里攒着的题更多更有选择的空间。 如果正着贪心的话就是,当前能做就立马提交,如果当前的时间更优但选不了就从之前…

完整教程:微软 Azure AI 视频翻译服务助力 JowoAI 实现短剧高效出海

完整教程:微软 Azure AI 视频翻译服务助力 JowoAI 实现短剧高效出海pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…

2025 年高可靠性测试设备/HALT/HASS/Halt/Hass/厂家制造商推荐榜:聚焦高效质量解决方案,助力企业产品升级

随着制造业升级加速、高端产品对可靠性要求提升及全球市场对质量标准的严格化,高可靠性测试设备已从特定行业需求逐步成为电子、汽车、航空航天等领域的必备工具,2025 年市场规模预计持续增长。但市场扩张也带来厂商…

八字手链人物传记计划——旭

写在前面1542 字 | 朋友 | 感触 | 生活细节 | 经历 | 生活灵珍琴懿,骆旭泽予。 正文我与旭已经四年没有联系过了。自初中以后,他似乎消失了一般。后面听人说,他去学了医。我很难想象,那个憨厚老实的一个胖胖孩子,…

详细介绍:c# datagridview添加list内容

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20232309 2025-2026-1 《网络与系统攻防技术》实验一实验报告

1.实验内容 1.1学习内容缓冲区漏洞的概念,发展历程,经典案例 缓冲区溢出的基本知识gdb的基本操作:break、step、stepi、continue等 基本汇编指令:push、pop、ret、call等 栈结构:环境变量/参数和个数以及主函数和…

亚马逊发布基于Linux的Vega OS电视系统,禁止侧载应用

亚马逊正式推出基于Linux的Vega OS电视操作系统,取代基于Android的Fire OS。新系统仅支持亚马逊应用商店,禁止侧载应用,性能更高效但内存要求更低,目前仅在新款Fire TV 4K Select上提供。亚马逊发布基于Linux的Veg…

.net9.0 JWT AUTH2.0 添加身份认证授权

1、添加 Microsoft.AspNetCore.Authentication.JwtBearer 包(9.0.9) 2、 添加类 public class TokenParameter { public const string Issuer = "aa";//颁发者 public const string Audience = "bb&q…

实用指南:同时使用ReactUse 、 ahooks与性能优化

实用指南:同时使用ReactUse 、 ahooks与性能优化2025-10-11 12:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; displa…

解决vscode中用npm报错

在终端运行npm run serve显示 npm : 无法加载文件 D:\nodejs\npm.ps1,因为在此系统上禁止运行脚本 看一些网友建议说用管理员身份运行vscode,打开后问题仍未解决。 准备参考https://blog.csdn.net/weixin_48475651/a…

MATLAB复杂曲线曲面造型及导函数实现

一、复杂曲线曲面造型方法 1.1 样条插值技术 1.1.1 Catmull-Rom样条数学原理:通过控制点构建分段三次多项式曲线,保证切线连续性MATLAB实现: function p = catmull_rom(p0,p1,p2,p3,nPoints)dt = 1/(nPoints-1);t =…

2025 年最新月嫂培训机构推荐榜单:短期 / 精英 / 金牌 / 高端月嫂培训及就业推荐,精选优质机构

随着母婴护理需求的持续攀升,月嫂行业成为热门职业选择,各类月嫂培训机构也如雨后春笋般涌现。但当前市场乱象频发,部分机构课程体系不完善、实操训练不足,导致学员毕业后难以胜任工作;还有机构以 “高薪就业”“…

【C++实战㊳】C++单例模式:从理论到实战的深度剖析 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …