18 #include <opencv2/opencv.hpp>
19 #include <yarp/cv/Cv.h>
20 #include "classifier.h"
22 using namespace yarp::cv;
24 #define CMD_TRAIN yarp::os::createVocab32('t','r','a','i')
25 #define CMD_CLASSIFY yarp::os::createVocab32('c','l','a','s')
26 #define CMD_FORGET yarp::os::createVocab32('f','o','r','g')
27 #define CMD_BURST yarp::os::createVocab32('b','u','r','s')
28 #define CMD_LIST yarp::os::createVocab32('l','i','s','t')
29 #define CMD_CHANGE_NAME yarp::os::createVocab32('c','h','n','a')
32 bool Classifier::configure(yarp::os::ResourceFinder &rf)
34 string moduleName = rf.check(
"name",Value(
"himrepClassifier"),
"module name (string)").asString();
35 setName(moduleName.c_str());
37 rpcClassifier.open(
"/"+moduleName+
"/classify:rpc");
38 imgInput.open(
"/"+moduleName+
"/img:i");
39 imgSIFTInput.open(
"/"+moduleName+
"/SIFTimg:i");
40 imgOutput.open(
"/"+moduleName+
"/img:o");
41 scoresInput.open(
"/"+moduleName+
"/scores:i");
42 rpcPort.open(
"/"+moduleName+
"/rpc");
44 featureInput.open(
"/"+moduleName+
"/features:i");
45 featureOutput.open(
"/"+moduleName+
"/features:o");
47 imgSIFTOutput.open(
"/"+moduleName+
"/SIFTimg:o");
48 opcPort.open(
"/"+moduleName+
"/opc");
60 bool Classifier::interruptModule()
63 imgOutput.interrupt();
64 rpcClassifier.interrupt();
65 scoresInput.interrupt();
67 imgSIFTInput.interrupt();
68 imgSIFTOutput.interrupt();
74 bool Classifier::close()
78 rpcClassifier.close();
82 imgSIFTOutput.close();
88 bool Classifier::getOPCList(Bottle &names)
91 if (opcPort.getOutputCount()>0)
93 Bottle opcCmd,opcReply,opcReplyProp;
94 opcCmd.addVocab32(
"ask");
95 Bottle &content=opcCmd.addList().addList();
96 content.addString(
"entity");
97 content.addString(
"==");
98 content.addString(
"object");
99 opcPort.write(opcCmd,opcReply);
101 if (opcReply.size()>1)
103 if (opcReply.get(0).asVocab32()==Vocab32::encode(
"ack"))
105 if (Bottle *idField=opcReply.get(1).asList())
107 if (Bottle *idValues=idField->get(1).asList())
110 for (
int i=0; i<idValues->size(); i++)
112 int id=idValues->get(i).asInt32();
117 opcCmd.addVocab32(
"get");
118 Bottle &content=opcCmd.addList();
119 Bottle &list_bid=content.addList();
120 list_bid.addString(
"id");
121 list_bid.addInt32(
id);
122 Bottle &list_propSet=content.addList();
123 list_propSet.addString(
"propSet");
124 list_propSet.addList().addString(
"name");
125 opcPort.write(opcCmd,opcReplyProp);
128 if (opcReplyProp.get(0).asVocab32()==Vocab32::encode(
"ack"))
129 if (Bottle *propField=opcReplyProp.get(1).asList())
130 if (propField->check(
"name"))
131 names.addString(propField->find(
"name").asString());
145 bool Classifier::updateObjDatabase()
147 lock_guard<mutex> lg(mtx);
148 if ((opcPort.getOutputCount()==0) || (rpcClassifier.getOutputCount()==0))
153 bool success=getOPCList(opcObjList);
156 printf(
"Error in communicating with OPC \n");
161 Bottle cmdObjClass,objClassList;
162 cmdObjClass.addString(
"objList");
163 rpcClassifier.write(cmdObjClass,objClassList);
164 if (objClassList.get(0).asString()==
"ack")
166 if (Bottle *objList=objClassList.get(1).asList())
168 for (
int k=0; k<objList->size(); k++)
170 string currObj=objList->get(k).asString();
171 if (currObj==
"background")
176 for (
int i=0; i<opcObjList.size(); i++)
178 string opcObj=opcObjList.get(i).asString();
179 if (currObj.compare(opcObj)==0)
189 printf(
"****** Deleting %s ..... \n",currObj.c_str());
191 cmdObjClass.addString(
"forget");
192 cmdObjClass.addString(currObj);
194 rpcClassifier.write(cmdObjClass,repClass);
195 printf(
"****** Deleted %s ..... \n",currObj.c_str());
202 Bottle cmdTr,trReply;
203 cmdTr.addString(
"train");
204 rpcClassifier.write(cmdTr,trReply);
205 printf(
"****** Retrained ..... \n");
211 bool Classifier::train(Bottle *locations, Bottle &reply)
216 string object_name=locations->get(0).asList()->get(0).asString();
218 currObject=object_name;
224 cmdClass.addString(
"save");
225 cmdClass.addString(object_name);
228 printf(
"Sending training request: %s\n",cmdClass.toString().c_str());
229 rpcClassifier.write(cmdClass,classReply);
230 printf(
"Received reply: %s\n",classReply.toString().c_str());
234 ImageOf<PixelRgb> *image=imgInput.read();
238 Bottle* bb=locations->get(0).asList()->get(1).asList();
239 int x_min=bb->get(0).asInt32();
240 int y_min=bb->get(1).asInt32();
241 int x_max=bb->get(2).asInt32();
242 int y_max=bb->get(3).asInt32();
250 if ((x_max+5)<image->width())
253 if ((y_max+5)<image->height())
256 int blobW=x_max-x_min;
257 int blobH=y_max-y_min;
260 ImageOf<PixelRgb> tmp_img = *image;
261 ::cv::Mat mat_tmp_img = toCvMat(tmp_img);
262 ::cv::Mat mat_croppedImg = mat_tmp_img(cv::Rect(x_min,y_min,blobW,blobH)).clone();
263 ImageOf<PixelRgb> croppedImg = fromCvMat<PixelRgb>(mat_croppedImg);
266 imgOutput.write(croppedImg);
270 featureInput.read(fea);
276 trainingFeature.push_back(fea);
278 featureOutput.write(fea);
284 cmdTr.addString(
"train");
286 printf(
"Sending training request: %s\n",cmdTr.toString().c_str());
287 rpcClassifier.write(cmdTr,trReply);
288 printf(
"Received reply: %s\n",trReply.toString().c_str());
291 reply.addString(
"ack");
296 void Classifier::classify(Bottle *blobs, Bottle &reply)
304 if (blobs->size()==0)
310 if ((imgInput.getInputCount()==0) || (imgSIFTInput.getInputCount()==0) ||
311 (featureInput.getInputCount()==0) || (scoresInput.getInputCount()==0) ||
312 (rpcClassifier.getOutputCount()==0))
319 Bottle cmdObjClass,objClassList;
320 cmdObjClass.addString(
"objList");
321 rpcClassifier.write(cmdObjClass,objClassList);
322 if (objClassList.get(0).asString()!=
"ack")
325 Bottle *objList=objClassList.get(1).asList();
329 if (objList->size()==0)
331 for (
int b=0; b<blobs->size(); b++)
333 Bottle &blob_scorelist=reply.addList();
334 blob_scorelist.addString(blobs->get(b).asList()->get(0).asString());
335 blob_scorelist.addList();
341 Bottle cmdClass,classReply;
342 cmdClass.addString(
"recognize");
343 rpcClassifier.write(cmdClass,classReply);
344 if (classReply.get(0).asString()==
"nack")
351 ImageOf<PixelRgb> *image=imgInput.read();
356 printf(
"Start classification\n");
357 for (
int b=0; b<blobs->size(); b++)
360 Bottle &blob_scorelist=reply.addList();
362 blob_scorelist.addString(blobs->get(b).asList()->get(0).asString());
364 Bottle &scores=blob_scorelist.addList();
366 Bottle *bb=blobs->get(b).asList()->get(1).asList();
367 int x_min=(int)bb->get(0).asFloat64();
368 int y_min=(int)bb->get(1).asFloat64();
369 int x_max=(int)bb->get(2).asFloat64();
370 int y_max=(int)bb->get(3).asFloat64();
378 if ((x_max+5)<image->width())
381 if ((y_max+5)<image->height())
385 ImageOf<PixelRgb> tmp_img = *image;
386 ::cv::Mat mat_tmp_img = toCvMat(tmp_img);
387 ::cv::Mat mat_croppedImg = mat_tmp_img(cv::Rect(x_min,y_min,x_max-x_min,y_max-y_min)).clone();
388 ImageOf<PixelRgb> croppedImg = fromCvMat<PixelRgb>(mat_croppedImg);
391 imgOutput.write(croppedImg);
395 featureInput.read(fea);
396 ImageOf<PixelRgb> *imgSift=imgSIFTInput.read();
397 if ((fea.size()==0) || (imgSift==NULL))
400 x_max=std::min(x_min+imgSift->width(),image->width()-1);
401 y_max=std::min(y_min+imgSift->height(),image->height()-1);
402 toCvMat(*imgSift)(cv::Rect(0,0,x_max-x_min,y_max-y_min)).copyTo(mat_tmp_img(cv::Rect(x_min,y_min,x_max-x_min,y_max-y_min)));
403 *image = fromCvMat<PixelRgb>(mat_tmp_img);
406 featureOutput.write(fea);
410 scoresInput.read(class_scores);
411 if (class_scores.size()==0)
415 printf(
"Scores received: ");
416 for (
int i=0; i<objList->size(); i++)
418 Bottle *obj=class_scores.get(i).asList();
419 if (obj->get(0).asString()==
"background")
422 Bottle &currObj_score=scores.addList();
423 currObj_score.addString(obj->get(0).asString());
424 double normalizedVal=((obj->get(1).asFloat64())+1.0)/2.0;
425 currObj_score.addFloat64(normalizedVal);
426 printf(
"(%s %g) ",obj->get(0).asString().c_str(),normalizedVal);
432 if (imgSIFTOutput.getOutputCount()>0)
434 imgSIFTOutput.prepare()=*image;
435 imgSIFTOutput.write();
440 bool Classifier::respond(
const Bottle& command, Bottle& reply)
442 lock_guard<mutex> lg(mtx);
443 switch(command.get(0).asVocab32())
449 train(command.get(1).asList(),reply);
455 classify(command.get(1).asList(),reply);
461 string className=command.get(1).asString();
463 cmdObjClass.addString(
"forget");
464 cmdObjClass.addString(className);
466 printf(
"Sending training request: %s\n",cmdObjClass.toString().c_str());
467 rpcClassifier.write(cmdObjClass,repClass);
468 printf(
"Received reply: %s\n",repClass.toString().c_str());
469 reply.addString(
"ack");
475 string cmd=command.get(1).asString();
478 trainingFeature.clear();
487 cmdClass.addString(
"save");
488 cmdClass.addString(currObject);
490 rpcClassifier.write(cmdClass,classReply);
492 for (
size_t i=0; i<trainingFeature.size(); i++)
493 featureOutput.write(trainingFeature[i]);
495 trainingFeature.clear();
498 cmdTr.addString(
"train");
500 rpcClassifier.write(cmdTr,trReply);
503 reply.addString(
"ack");
510 cmdList.addString(
"objList");
511 printf(
"Sending list request: %s\n",cmdList.toString().c_str());
512 rpcClassifier.write(cmdList,reply);
513 printf(
"Received reply: %s\n",reply.toString().c_str());
517 case CMD_CHANGE_NAME:
519 string oldName=command.get(1).asString();
520 string newName=command.get(2).asString();
523 cmdList.addString(
"changeName");
524 cmdList.addString(oldName);
525 cmdList.addString(newName);
526 printf(
"Sending change name request: %s\n",cmdList.toString().c_str());
527 rpcClassifier.write(cmdList,reply);
528 printf(
"Received reply: %s\n",reply.toString().c_str());
533 reply.addString(
"nack");
538 double Classifier::getPeriod()
544 bool Classifier::updateModule()
548 printf(
"Trying to start Synchronization with OPC... \n");
549 if (updateObjDatabase())
551 printf(
"Synchronization with OPC Completed... \n");