29 #include <opencv2/opencv.hpp>
30 #include <opencv2/imgproc/types_c.h>
32 #include <yarp/os/Network.h>
33 #include <yarp/os/RFModule.h>
34 #include <yarp/os/Time.h>
35 #include <yarp/os/BufferedPort.h>
36 #include <yarp/os/RpcClient.h>
37 #include <yarp/os/PortReport.h>
38 #include <yarp/os/Stamp.h>
40 #include <yarp/sig/Vector.h>
41 #include <yarp/sig/Image.h>
43 #include <yarp/cv/Cv.h>
45 #include <yarp/math/Math.h>
47 #include "GIEFeatExtractor.h"
51 using namespace yarp::os;
52 using namespace yarp::sig;
53 using namespace yarp::cv;
54 using namespace yarp::math;
56 #define CMD_HELP yarp::os::createVocab32('h','e','l','p')
57 #define DUMP_CODE yarp::os::createVocab32('d','u','m','p')
58 #define DUMP_STOP yarp::os::createVocab32('s','t','o','p')
60 class GIECoderPort:
public BufferedPort<Image>
88 GIEFeatExtractor *gie_extractor;
90 void onRead(Image &img)
93 if (Time::now() - last_read < rate)
96 lock_guard<mutex> lg(mtx);
99 if (img.width()>0 && img.height()>0)
103 cv::Mat tmp_mat = toCvMat(img);
104 cv::cvtColor(tmp_mat, matImg, CV_RGB2BGR);
108 std::vector<float> codingVecFloat;
110 if (!gie_extractor->extract_singleFeat_1D(matImg, codingVecFloat, times))
112 std::cout <<
"GIEFeatExtractor::extract_singleFeat_1D(): failed..." << std::endl;
115 std::vector<double> codingVec(codingVecFloat.begin(), codingVecFloat.end());
117 if (gie_extractor->timing)
119 std::cout << times[0] <<
": PREP " << times[1] <<
": NET" << std::endl;
124 fwrite (&codingVec[0],
sizeof(
double), codingVec.size(), fout_code);
128 this->getEnvelope(stamp);
130 if (port_out_code.getOutputCount())
132 port_out_code.setEnvelope(stamp);
133 yarp::sig::Vector codingYarpVec(codingVec.size(), &codingVec[0]);
134 port_out_code.write(codingYarpVec);
137 if (port_out_img.getOutputCount())
139 port_out_img.write(img);
146 GIECoderPort(ResourceFinder &_rf) :BufferedPort<Image>(),rf(_rf)
149 contextPath = rf.getHomeContextPath().c_str();
154 string caffemodel_file = rf.check(
"caffemodel_file", Value(
"bvlc_googlenet.caffemodel")).asString().c_str();
155 cout <<
"Setting .caffemodel file to " << caffemodel_file << endl;
158 string prototxt_file = rf.check(
"prototxt_file", Value(
"deploy.prototxt")).asString().c_str();
159 cout <<
"Setting .prototxt file to " << prototxt_file << endl;
162 string blob_name = rf.check(
"blob_name", Value(
"pool5/7x7_s1")).asString().c_str();
165 bool timing = rf.check(
"timing",Value(
false)).asBool();
167 string binaryproto_meanfile =
"";
168 float meanR = -1, meanG = -1, meanB = -1;
169 int resizeWidth = -1, resizeHeight = -1;
170 if (rf.find(
"binaryproto_meanfile").isNull() && rf.find(
"meanR").isNull())
172 cout <<
"ERROR: missing mean info!!!!!" << endl;
174 else if (rf.find(
"binaryproto_meanfile").isNull())
176 meanR = rf.check(
"meanR", Value(123)).asFloat64();
177 meanG = rf.check(
"meanG", Value(117)).asFloat64();
178 meanB = rf.check(
"meanB", Value(104)).asFloat64();
179 resizeWidth = rf.check(
"resizeWidth", Value(256)).asFloat64();
180 resizeHeight = rf.check(
"resizeHeight", Value(256)).asFloat64();
181 std::cout <<
"Setting mean to " <<
" R: " << meanR <<
" G: " << meanG <<
" B: " << meanB << std::endl;
182 std::cout <<
"Resizing anysotropically to " <<
" W: " << resizeWidth <<
" H: " << resizeHeight << std::endl;
185 else if (rf.find(
"meanR").isNull())
187 binaryproto_meanfile = rf.check(
"binaryproto_meanfile", Value(
"imagenet_mean.binaryproto")).asString().c_str();
188 cout <<
"Setting .binaryproto file to " << binaryproto_meanfile << endl;
192 std::cout <<
"ERROR: need EITHER mean file (.binaryproto) OR mean pixel values!" << std::endl;
195 gie_extractor =
new GIEFeatExtractor(caffemodel_file, binaryproto_meanfile, meanR, meanG, meanB,
196 prototxt_file, resizeWidth, resizeHeight,
201 cout <<
"Failed to initialize GIEFeatExtractor" << endl;
206 string name = rf.find(
"name").asString().c_str();
208 port_out_img.open((
"/"+name+
"/img:o").c_str());
209 port_out_code.open((
"/"+name+
"/code:o").c_str());
211 BufferedPort<Image>::useCallback();
213 rate = rf.check(
"rate",Value(0.0)).asFloat64();
216 dump_code = rf.check(
"dump_code");
219 string code_path = rf.check(
"dump_code",Value(
"codes.bin")).asString().c_str();
220 code_path = contextPath +
"/" + code_path;
221 string code_write_mode = rf.check(
"append")?
"wb+":
"wb";
223 fout_code = fopen(code_path.c_str(),code_write_mode.c_str());
229 lock_guard<mutex> lg(mtx);
231 port_out_code.interrupt();
232 port_out_img.interrupt();
234 BufferedPort<Image>::interrupt();
239 lock_guard<mutex> lg(mtx);
241 port_out_code.resume();
242 port_out_img.resume();
244 BufferedPort<Image>::resume();
249 lock_guard<mutex> lg(mtx);
256 port_out_code.close();
257 port_out_img.close();
259 delete gie_extractor;
261 BufferedPort<Image>::close();
264 bool execReq(
const Bottle &command, Bottle &reply)
266 switch(command.get(0).asVocab32())
271 reply.add(Value::makeVocab32(
"many"));
272 reply.addString(
"[dump] [path-to-file] [a] to start dumping the codes in the context directory. Use 'a' for appending.");
273 reply.addString(
"[stop] to stop dumping.");
279 lock_guard<mutex> lg(mtx);
283 string code_write_mode;
285 if (command.size()==1)
287 code_path = contextPath +
"/codes.bin";
288 code_write_mode=
"wb";
290 else if (command.size()==2)
292 if (strcmp(command.get(1).asString().c_str(),
"a")==0)
294 code_write_mode=
"wb+";
295 code_path = contextPath +
"/codes.bin";
298 code_write_mode=
"wb";
299 code_path = command.get(1).asString().c_str();
301 }
else if (command.size()==3)
303 code_write_mode=
"wb+";
304 code_path = command.get(2).asString().c_str();
307 fout_code = fopen(code_path.c_str(),code_write_mode.c_str());
308 reply.addString(
"Start dumping codes...");
315 lock_guard<mutex> lg(mtx);
319 reply.addString(
"Stopped code dump.");
331 class GIECoderModule:
public RFModule
334 GIECoderPort *GIEPort;
344 bool configure(ResourceFinder &rf)
346 string name = rf.find(
"name").asString().c_str();
348 GIEPort =
new GIECoderPort(rf);
350 GIEPort->open((
"/"+name+
"/img:i").c_str());
352 rpcPort.open((
"/"+name+
"/rpc").c_str());
358 bool interruptModule()
361 GIEPort->interrupt();
381 bool respond(
const Bottle &command, Bottle &reply)
383 if (GIEPort->execReq(command,reply))
386 return RFModule::respond(command,reply);
389 double getPeriod() {
return 1.0; }
398 int main(
int argc,
char *argv[])
401 if (!yarp.checkNetwork())
405 rf.setDefaultContext(
"himrep");
406 rf.setDefaultConfigFile(
"GIECoder_googlenet.ini");
407 rf.configure(argc,argv);
408 rf.setDefault(
"name",
"GIECoder");
411 return mod.runModule(rf);