<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      象棋圖片轉FEN字符串詳細教程

      如把下圖

      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 Path
      
      fn = 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 * S
          x = L + xx * S
          id.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 move
      
      s = '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 pickle
      
      data_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): continue
        for 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: continue
          feature = extract_features(img)
          if feature is None: continue
          features.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 pickle
      
      b = [[' '] * 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 = 0
         for x in range(9):
          c = b[y][x]
          if c == '0': n += 1
          else:
           if n: f += str(n)
           f += c; n = 0
         if n: f += str(n)
         if y != 9: f += '/'
        return f
      
      print(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 sys
      
      def size (W, H):
        S = 68 if W == 640 else 86 # size
        L = (W - 9 * S) // 2 # left
        T = (H - 10 * S) // 2 # top
        return S,L,T
      
      def 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 & radius
        for y in range(S):
          for x in range(S):
            # 圓形mask. hypotenuse: 斜邊
            if np.hypot(x - HS, y - HS) > R: mask[y, x] = True
      
        for yy in range(10):
          for xx in range(9):
            x = L + xx * S; y = T + yy * S
            x2 = min(W, x + S); y2 = min(H, y + S)
            sl = img[y:y2, x:x2]; sl[mask] = 0
            all.append(sl)
      
        return all
      
      def 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 None
      
        contour = 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 os
      
      fn = 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 circles
        param1=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] = True
      
      for 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

      七 補充

      ① train.py和predict.py不用import pickle, common.py import了。

      ② 在我機器上,用OpenCV顯示圖像,出來后卡死了,Ctrl-C都不行得kill。PIL的show先在/tmp下存文件再用系統默認圖片查看器打開。OpenCV應該是因為我亂改KDE配置壞的事。

       t

      這個tough. 死活只能找到31個棋子,帶框的炮不行。

      posted @ 2025-10-11 12:51  華容道專家  閱讀(10)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美成本人视频免费播放| 亚洲男人天堂东京热加勒比| AV区无码字幕中文色| 日本边添边摸边做边爱的网站| 伊人久久久av老熟妇色| 九九热精品在线视频观看| 国产高清一区二区三区视频| 欧美一区二区三区成人久久片| 悠悠人体艺术视频在线播放 | 中文字幕久久波多野结衣av| 亚洲男女羞羞无遮挡久久丫| 99在线精品免费视频| 国产一区二区黄色激情片| 在线 欧美 中文 亚洲 精品| 人妻熟女av一区二区三区| 国产精品白浆无码流出| 亚洲国产成人久久精品APP| 国产蜜臀av在线一区二区| 亚洲韩国精品无码一区二区三区| 欧美老少配性行为| 国产免费人成网站在线播放| 国产精品中文字幕一区| 一本本月无码-| 欧美日韩在线亚洲二区综二| 日日躁夜夜躁狠狠躁超碰97| 国产成人a在线观看视频| 日本黄色三级一区二区三区| 久久精品国产亚洲AV瑜伽| 在线无码免费的毛片视频| 国产成人高清亚洲综合| 福利一区二区在线播放| 中国女人熟毛茸茸A毛片| 公天天吃我奶躁我的在| 97色伦97色伦国产| 午夜DY888国产精品影院 | 久热这里有精品视频播放| 亚洲 都市 无码 校园 激情| 久久99精品国产99久久6男男| 久久久久久国产精品美女| 亚洲精品国产一二三区| 日韩黄色av一区二区三区|