#include #include #include #include #include #include #include #include #include #include #include #include #include #include GUI gui("hbox"); GUI zoomGUI; static Point zoomCenter(320,240); void init(){ int masksize = 10; int thresh = 2; int gamma = 0; if(pa_defined("-config")){ std::string configFileName = pa_subarg("-config",0,""); if(configFileName == "") goto END; ConfigFile f; f.load(configFileName); masksize = f.get("config.masksize"); thresh = f.get("config.threshold"); gamma = f.get("config.gammaslope"); } END: gui << "image[@minsize=32x24@handle=orig@label=original]"; gui << "image[@minsize=32x24@handle=prev@label=preview]"; gui << ( GUI("vbox[@label=controls]") << string("slider(2,200,")+str(masksize)+")[@label=mask size@out=masksize@minsize=15x2]" << string("slider(-30,40,")+str(thresh)+")[@label=threshold@out=threshold@minsize=15x2]" << string("fslider(0,15,")+str(gamma)+")[@label=gamma slope@out=gamma@minsize=15x2]" << "button(next image)[@handle=next]" << "togglebutton(stopped,running)[@out=run]" << "button(save params)[@handle=save]" ); gui.show(); zoomGUI << "image[@minsize=32x24@handle=zoom@label=zoom]"; zoomGUI.show(); } void mouse(const MouseEvent &event){ if(event.isPressEvent() || event.isDragEvent()){ zoomCenter = event.getPos(); } } void save(){ static int &masksize = gui.getValue("masksize"); static int &thresh = gui.getValue("threshold"); static float &gamma = gui.getValue("gamma"); bool ok = false; QString qname = QInputDialog::getText(0,"Save Params", "Please specify output xml-file name" ,QLineEdit::Normal,"local-threshold-params.xml",&ok); if(ok){ ConfigFile f; f.set("config.masksize",masksize); f.set("config.threshold",thresh); f.set("config.gammaslope",gamma); f.save(qname.toLatin1().data()); } } void update_zoom(Img8u &prevImage){ static ImageHandle &h= zoomGUI.getValue("zoom"); Point p = zoomCenter; if(!prevImage.getImageRect().contains(p.x,p.y)) return; static const Size zoomSize = parse(pa_subarg("-zoomsize",0,"640x480")); static Img8u zoomRegion(zoomSize,formatGray); prevImage.setROI(Rect(p.x-zoomSize.width/2,p.y-zoomSize.height/2,zoomSize.width,zoomSize.height) & prevImage.getImageRect()); if(prevImage.getROISize() == zoomSize){ prevImage.deepCopyROI(&zoomRegion); } prevImage.setFullROI(); h = zoomRegion; h.update(); } void run(){ static GenericGrabber g(pa_subarg("-input",0,"pwc,dc,file"), pa_subarg("-input",1,"pwc=0,dc=0,file=images/*.ppm")); if(g.getType() == "file"){ g.setIgnoreDesiredParams(true); }else{ g.setDesiredSize(Size(640,480)); g.setDesiredFormat(formatGray); g.setDesiredDepth(depth8u); } static ImageHandle &orig = gui.getValue("orig"); static ImageHandle &prev = gui.getValue("prev"); (*prev)->install(new MouseHandler(mouse)); static ButtonHandle &next = gui.getValue("next"); static bool &loop = gui.getValue("run"); static int &masksize = gui.getValue("masksize"); static int &thresh = gui.getValue("threshold"); static float &gamma = gui.getValue("gamma"); gui.getValue("save").registerCallback(new GUI::Callback(save)); static LocalThresholdOp t; static int lastMaskSize=0; static int lastThresh=0; static float lastGamma=0; static Point lastZoomCenter = zoomCenter; while(1){ t.setMaskSize(masksize); t.setGlobalThreshold(thresh); t.setGammaSlope(gamma); const ImgBase *image = g.grab(); if(image->getFormat() != formatGray){ static ImgBase *grayImage = 0; ensureCompatible(&grayImage,depth8u,image->getSize(),formatGray); cc(image,grayImage); image = grayImage; } static ImgBase *dst = 0; t.apply(image,&dst); orig = image; orig.update(); prev = dst; prev.update(); update_zoom(*dst->asImg()); lastMaskSize = masksize; lastThresh = thresh; lastGamma = gamma; lastZoomCenter = zoomCenter; while(!loop && !next.wasTriggered()){ Thread::msleep(100); if(lastMaskSize != masksize || lastThresh != thresh || lastGamma != gamma){ t.setMaskSize(masksize); t.setGlobalThreshold(thresh); t.setGammaSlope(gamma); lastMaskSize = masksize; lastThresh = thresh; lastGamma = gamma; t.apply(image,&dst); orig = image; orig.update(); prev = dst; prev.update(); update_zoom(*dst->asImg()); lastZoomCenter = zoomCenter; } else if(lastZoomCenter != zoomCenter){ update_zoom(*dst->asImg()); lastZoomCenter = zoomCenter; } } Thread::msleep(20); } } void batch_mode(){ if(pa_defined("-config")){ std::string configFileName = pa_subarg("-config",0,""); if(configFileName == ""){ ERROR_LOG("no config filename !"); return; } printf("filename = -%s- \n",configFileName.c_str()); ConfigFile f; f.load(configFileName); int masksize = f.get("config.masksize"); int thresh = f.get("config.threshold"); float gamma = f.get("config.gammaslope"); if(!pa_defined("-output")){ printf("please specify output file pattern\n"); return; } if(!pa_defined("-input") || (pa_subarg("-input",0,"") != "file")){ printf("please define args -input file filename!\n"); return; } string inputFilePattern = pa_subarg("-input",1,"images/*.ppm"); if(inputFilePattern.find("file=") == 0){ inputFilePattern = inputFilePattern.substr(5); } printf("input file pattern was %s \n",inputFilePattern.c_str()); static FileGrabber g(inputFilePattern); g.setIgnoreDesiredParams(true); static FileWriter w(pa_subarg("-output",0,"./local_threshold_image_######.jpg")); static LocalThresholdOp t; t.setMaskSize(masksize); t.setGlobalThreshold(thresh); t.setGammaSlope(gamma); int fileCount = g.getFileCount(); while(fileCount--){ printf("processing image %30s ......",g.getNextFileName().c_str()); const ImgBase *image = g.grab(); if(image->getFormat() != formatGray){ printf("..."); static ImgBase *grayImage = 0; ensureCompatible(&grayImage,depth8u,image->getSize(),formatGray); cc(image,grayImage); printf("..."); image = grayImage; } static ImgBase *dst = 0; printf("..."); t.apply(image,&dst); printf("..."); w.write(dst); printf("done! \n"); printf("writing image to %30s ... done\n",w.getFilenameGenerator().showNext().c_str()); } }else{ ERROR_LOG("please run with -config config-filename!"); return; } } /* Call e.g. examples/local_threshold -nogui -input file 'file=/home/celbrech/Desktop/Bilder/ *jpg' -config ./local-threshold-params.xml -output './images/image_#####.ppm' */ int main (int argc, char **argv) { pa_explain("-input","generic-grabbers generic grabbers params"); pa_explain("-config","config file input"); pa_explain("-zoomsize","size of zoom preview image (e.g. -zoom 320x240)"); pa_explain("-nogui","start without gui"); pa_explain("-output","for no gui batchmode: define output-image pattern"); pa_init(argc,argv,"-input(2) -output(1) -config(1) -zoomsize(1) -nogui"); if(pa_defined("-nogui")){ batch_mode(); }else{ ExecThread x(run); QApplication app(argc,argv); init(); x.run(); return app.exec(); } }