Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

66
LINES

< > BotCompany Repo | #1024689 // ChessPieceRecognizer

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (7473L/50K).

// thread-safe except for analysis output fields
sclass ChessPieceRecognizer {
  MultiMap<S, ChessPieceProfile1> profiles;
  double magicCombineFactor = 0.0012589254117941495;
  int version = 1;
  
  // for analysis
  transient Pair<Pair<S, ChessPieceProfile1>, Double> best, runnerUp;
  
  void load {
    long time = sysNow();
    profiles = agiBlue_chessPieceProfiles(agiBlue_chessPieceImages_loadedMultiMap(), +version);
    compact();
    done2("Loading " + n2(l(profiles), "piece profile"), time);
  }
  
  void compact {
    int n = l(profiles);
    profiles = uniquifyMultiMapValues(profiles);
    int m = l(profiles);
    if (m < n)
      print("Compacted ChessPieceRecognizer " + n + " => " + m);
    internByteArrayField sideProfile(values(profiles));
  }
  
  Pair<S, Double> recognize(BufferedImage img) {
    ChessPieceProfile1 profile = chessOCR_pieceProfileFromRawImage_1(img);
    new Lowest_withRunnerUp<Pair<S, ChessPieceProfile1>> lowest;
    
    for (unpair S piece, ChessPieceProfile1 p : multiMapToPairs(profiles)) {
      float sideProfileDiff = floatRatio(byteArraysTotalDiff(profile.sideProfile, p.sideProfile), l(p.sideProfile));
      float fillGradeDiff = abs(profile.fillGrade-p.fillGrade);
      double score = magicCombine(sideProfileDiff, fillGradeDiff);
      lowest.put(pair(piece, p), score);
    }
    best = lowest.pair();
    runnerUp = lowest.runnerUpPair();
    ret !lowest.has() ? null : pair(pairA(lowest!), errorToPercent(lowest.score()));
  }
  
  // for humans
  double errorToPercent(double d) {
    ret 100-d;
  }
  
  double magicCombine(double sideProfileScore, double fillGradeScore) {
    double sum = sideProfileScore+fillGradeScore/magicCombineFactor;
    //print("magicCombine " + sideProfileScore + "*" + magicCombineFactor + "+" + fillGradeScore + " = " + sum);
    ret sum;
  }
  
  toString {
    ret shortClassName(this) + "(v" + version + ", " + nProfiles(l(profiles)) + ")";
  }
  
  ChessOCR_RecognizedBoard recognizeBoard(BufferedImage board) {
    new ChessOCR_RecognizedBoard out;
    LL<BufferedImage> squareImages = bufferedImageMNGrid(board, 8, 8);
    out.pieces = new L;
    for (BufferedImage img : concatLists(squareImages))
      out.pieces.add(recognize(img));
    out.score = doubleAvg(pairsB(out.pieces));
    out.fen = chess_makeFEN(listToChunks(8, pairsA(out.pieces)));
    ret out;
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1024689
Snippet name: ChessPieceRecognizer
Eternal ID of this version: #1024689/47
Text MD5: 93d99af4deaacecb1663a2d71a8344d5
Transpilation MD5: 435cb478305a5a3887093a8a4c9cae64
Author: stefan
Category: javax / image recognition
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-08-28 16:45:35
Source code size: 2433 bytes / 66 lines
Pitched / IR pitched: No / No
Views / Downloads: 472 / 1005
Version history: 46 change(s)
Referenced in: #1024744 - ChessPieceRecognizer (old)
#1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)