C++神经网络开发包ANNIE
源代码在线查看: imagecompress.cpp
#include "ImageCompress.h" #include "Control.h" #include "Image.h" #include "Video.h" #include "annie/listeners.h" #include using namespace std; namespace annie { Images TileCompressor::cut(const Image &source) const { return makeSubimages(source, _partSize, _partSize); } Image *TileCompressor::compress(const Image &im) { Images images = cut(im); _py = im.getHeight() / _partSize; _px = im.getWidth() / _partSize; return compressTiles(images); } struct Runner : Video::Redrawer, public ImageCompressor::PartialListener { Runner() : orig(NULL), comp(NULL) {} Image *orig, *comp; //< even partial virtual void showProgress(const Image &partialResult) { comp = partialResult.clone(); forceRedraw(); } virtual void draw() { if(defaultControl["terminate"]) return; if(orig) { orig->display(); if(comp) comp->display(orig->getWidth()); } } virtual ~Runner() { delete(orig); //may be null delete(comp); } }; /// MLPCompressor //////////////// MLPCompressor::MLPCompressor(uint partSize, uint hidden1, uint hidden2, PublicValues &pv) : TileCompressor(partSize), _net(partSize * partSize, pv), _reshow(control.get("reshow")) { ASSERT(hidden1); _net.addLayer(hidden1); if(hidden2) _net.addLayer(hidden2); _net.addLayer(partSize * partSize); //out //full connection _net.connectLayer(0); _net.connectLayer(1); if(hidden2) _net.connectLayer(2); if(!_reshow) _reshow = 10; } void MLPCompressor::valueChanged(const Value &val) { if(val.name() == "epoch" && !((uint)control["epoch"] % (uint) _reshow)) { Image *i = getResult(); showPartialProgress(*i); delete(i); } } Image *MLPCompressor::compressTiles(const Images &images) { TrainingSet *ts = makeSubImageExamples(images, vectored); //init image examples cout ts->shuffle(); cout control.addListener(*this); _net.train(*ts, control["epochs"], 0.2, 0.1); control.removeListener(*this); delete(ts); return getResult(); } void MLPCompressor::fillExamples(const Images &images, TrainingSet &dest) { vector dontCare; TrainingSet *ts = makeSubImageExamples(images, dontCare); dest = *ts; //slowwwwwww delete(ts); } /** * Make 0,1 vector from vector of continuous values. * (usable e.g. to make a BW image from grayscale image) */ static void bwVector(Vector &v) { for(Vector::iterator i=v.begin(); i != v.end(); i++) { if(*i > 0.5) *i = 1.; else *i = 0.0; } } Image *MLPCompressor::getResult() { Image *res = new Image(_px * _partSize, _py * _partSize); #define P(Y, X) ((y) * _px + (x)) //construct the output for(uint y=0; y for(uint x=0; x Vector o = _net.getOutput(vectored[P(y,x)]); bwVector(o); Image *io = Image::fromVector(o, _partSize, true); res->setSubImage(*io, x * _partSize, y * _partSize); delete(io); } return res; } /// :: ///// /* void draw() { if(video->getWindowHeight() != drawing.getHeight() || video->getWindowWidth() != drawing.getWidth()) drawing.resize(video->getWindowWidth(), video->getWindowHeight()); cout drawing.display(); }*/ void runCompressor(ImageCompressor &ic, const char *image, bool gray) { /*Stepper stepper; control.addListener(stepper);*/ bool displayVideo = defaultControl["video"]; SimpleVisualiser visualiser; defaultControl.addListener(visualiser); Runner run; run.orig = Image::fromFile(image); if(gray) { Image *tmp = run.orig->toGray(); delete(run.orig); run.orig = tmp; } if(displayVideo) changeWindowSize(run.orig->getWidth() * 2, run.orig->getHeight()); run.setFullViewport(); if(displayVideo) getVideo()->addRedraw(&run); forceRedraw(); if(displayVideo) ic.setPartialListener(&run); run.comp = ic.compress(*run.orig); //TODO save ... if(displayVideo) { forceRedraw(); waitForKey(); } if(displayVideo) getVideo()->removeRedraw(&run); /*_net.save(argv[3]); b->toFile(argv[2]);*/ //remove listeners! } } //annie