!7 cmodule ChessBoardRecognizer { S segmenterPreset; ParameterizedSegmenter segmenter; S status; transient ReliableSingleThread rst = dm_rst(module(), r recognize); transient BufferedImage img, board; transient ImageSurface isInput, isBoard; visual withCalc(rst, jvsplit( jCenteredSection("Input image", jscroll_center(isInput = jImageSurface(img))), northCenterAndSouthWithMargins( centerAndEastWithMargin(withLabel("Segmenter preset: ", main.onChange(rst, dm_comboBox segmenterPreset(agiBlue_segmenterPresetNames()))), jbutton("Recognize", rst)), jCenteredSection("Chess board found", jscroll_center(isBoard = jImageSurface())), dm_rightAlignedLabel('status) ))); void recognize { segmenter = parameterizedSegmenterFromAGIBlue(segmenterPreset); if (segmenter == null) ret with infoBox(status("No segmenter")); //img = dm_shootScreenHidingOS(); if (isInput != null) img = isInput.getImage(); L rects = segmenter.get(img); if (empty(rects)) ret with status("No chess board found"); Rect r = first(rects); if (l(rects) > 1) status("More than one chess board found, choosing one"); else status("Chess board found at: " + r); board = clipBufferedImage(img, r); if (isBoard != null) isBoard.setImage( mergeBufferedImagesVertically( map(bufferedImageNVerticalSlices(8, board), i -> mergeBufferedImagesHorizontally(bufferedImageNHorizontalSlices(8, i))))); } S status(S status) { setField(+status); ret status; } O _getReloadData() { ret img; } void _setReloadData(BufferedImage img) { this.img = img; } void setImage(BufferedImage img) { this.img = img; if (isInput != null) isInput.setImage(img); rst.trigger(); } }