!7 replace Submission with BackgroundPlus. // TODO: print log problem cmodule2 BoxFinder > DynImageSurface { int nBoxes = 1; bool keepGoing; new Best best; transient RGBImage original; transient Thread recognizerThread; transient ImageSurface isBoxes; transient Submission rendered; S switchableFields() { ret "nBoxes keepGoing"; } visualize { JSpinner spinner = liveValueSpinner(dm_fieldLiveValue('nBoxes), 1, 50); main.onChange(spinner, r startRecognition ); ret jvsplit( vgrid(super.visualize(), jscroll_centered(isBoxes = imageSurface())), northAndCenter( withSideMargin(rightAlignedLine( dm_fieldCheckBox('keepGoing), jbutton("Start", r startRecognition), jbutton("Stop", r { cancelThread(recognizerThread) }), withLabel("Boxes:", spinner))), dm_printLogComponent())); } start { if (!hasImage()) setImage(whiteImage(50, 50)); // so we can paste... onNewImage = r startRecognition; doEvery(1.0, r renderBoxes); } double scoreImage(RGBImage image) { ret 100*(1.0-rgbDistance(image, original)); } void startRecognition enter { cancelThread(recognizerThread); recognizerThread = startThread(r { BufferedImage image = getImage(); final int w = image.getWidth(), h = image.getHeight(); print("Starting recognition on " + w + "*" + h + " image"); best = new Best; best.stringifier = f sfu; original = RGBImage(image); //new AIStrategy_RandomWithVariation strategy; new AIStrategy_Racer_RandomWithVary strategy; strategy.verbose = true; strategy.best = best; strategy.submit = func(Submission s) -> double { scoreImage(rgbRenderRenderable(w, h, s)) }; strategy.random = func -> Submission { randomBackgroundPlusBoxes(w, h, nBoxes) }; strategy.vary = func(Submission s) -> Submission { varyBackgroundPlusBoxes(s, w, h) }; if (keepGoing) runStrategyForever(best, strategy); else runStrategyWhileImprovement(best, strategy); print("Done"); persistMe(); }); } void renderBoxes enter { if (original != null && best! != rendered) { rendered = best!; isBoxes.setImage(renderRenderable(original.w(), original.h(), rendered)); } } }