!7 cmodule ImageSegmenter > DynImageSurface { // parameters float contrastThreshold = 0.5f; int blur; int gridSize = 2; DoubleRange widthRange = new(0, 1); DoubleRange heightRange = new(0, 1); DoubleRange xRange = new(0, 1); DoubleRange yRange = new(0, 1); // output L segments; transient JLabel lblFound; transient ReliableSingleThread rst = dm_rst(this, r segmentIt); visualize { JSlider slider = jLiveValueSlider(dm_fieldLiveValue('contrastThreshold)); main.onChange(slider, rst); JSpinner spinner = liveValueSpinner(dm_fieldLiveValue('gridSize), 2, 10); main.onChange(spinner, rst); JSpinner blurSpinner = liveValueSpinner(dm_fieldLiveValue('blur)); main.onChange(blurSpinner, rst); JComponent sup = super.visualize(); overlaySelectionsOnImageSurface(imageSurface, segments); ret withCenteredLinesBelow(sup, ll( withLabel("Blur:", blurSpinner), withLabel("Contrast Threshold:", slider), withLabel("Grid size:", spinner), jbutton("Segment", rst), withLabel("Segments found:", lblFound = jlabel(l_str(segments))), jPopDownButton_noText( "Show segments", rThread showSegments )), ll( withLabel("Width range:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('widthRange)), rst)), withLabel("Height range:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('heightRange)), rst))), ll( withLabel("X position:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('xRange)), rst)), withLabel("Y position:", main.onChange(doubleRangeLiveValueSlider(dm_fieldLiveValue('yRange)), rst)))); } start { if (!hasImage()) setImage(whiteImage(100, 100)); dm_vmBus_onMessage('newClipboardContents, voidfunc(O o) { if (o cast BufferedImage) thread { setImage(o); rst.trigger(); } }); } void segmentIt enter { if (!hasImage()) ret; int w = imageWidth(), h = imageHeight(); new AutoSegmenter as; as.g = gridSize; as.contrastThreshold = contrastThreshold; L segments = as.go(BWImage(getImage()); IntRange wr = doubleToIntRange_endPlus1(w, widthRange); IntRange hr = doubleToIntRange_endPlus1(h, heightRange); IntRange xr = doubleToIntRange_endPlus1(w, xRange); IntRange yr = doubleToIntRange_endPlus1(h, yRange); printVars_str(+wr, +hr, +xr, +yr); segments = filterRectsByWidthRange(segments, wr); segments = filterRectsByHeightRange(segments, hr); segments = filterRectsByCenterXRange(segments, xr); segments = filterRectsByCenterYRange(segments, yr); setField(+segments); setText(lblFound, l_str(segments)); overlaySelectionsOnImageSurface(imageSurface, segments); } void showSegments { L segments = this.segments; showImage(n2(segments, "segment") + " found", mergeBufferedImagesVertically(map(segments, r -> clipBufferedImage(getImage(), r)))); } }