asclass DynWebCamAnalyzer > DynImageSurfaceAndEnabled { switchable bool overlay; transient ReliableSingleThread rstUpdateImage = dm_rst(this, r updateImage); transient S info; transient JLabel lblInfo; transient L overlays; transient BufferedImage inputImage; transient int w, h; // will be set to width & height of inputImage transient bool analyzing; transient S tempInfo; transient RegularlyClearedAverage analysisTime = new(nto_10seconds()); // nanoseconds for analysis start { set zoomToWindowOnSetImage; dm_doEvery(100, rstUpdateImage); } afterVisualize { imageSurface_pixelated(imageSurface); containerAddFirst(buttons, lblInfo = dm_label info(), dm_checkBox('overlay)); } void updateImage enter { if (imageSurface == null || !enabled) ret; BufferedImage img = dm_webCamImage(); if (img == null || img == inputImage) ret; inputImage = img; w = img.getWidth(); h = img.getHeight(); long time = nanoTime(); pcall { set analyzing; tempInfo = null; prepareImage(); time = nanoTime(); analyzeImage(); } analyzing = false; analysisTime.add(nanoTime()-time); setInfo(joinNemptiesWithSpacedDot(tempInfo, "Recognition time: " + n2(iceil(analysisTime!)) + " ns")); BufferedImage img2 = img; if (overlay) pcall { drawOverlays(img2 = cloneBufferedImage(img)); } setImage(img2); } // overload me for preparation (e.g. making integral image) void prepareImage {} // overlord me, uh, i mean, overload me // can use inputImage, w, h and setInfo void analyzeImage() { } // overlooooad me if you want void drawOverlays(BufferedImage img) { renderRenderables(img, overlays); } void setInfo(S info) { if (analyzing) tempInfo = info; else setField(+info); } }