18 #include <yarp/sig/all.h> 19 #include "faceLandmarks.h" 22 bool FACEModule::configure(yarp::os::ResourceFinder &rf)
25 moduleName = rf.check(
"name", yarp::os::Value(
"faceLandmarks"),
"module name (string)").asString();
26 predictorFile = rf.check(
"faceLandmarksFile", yarp::os::Value(
"shape_predictor_68_face_landmarks.dat"),
"path name (string)").asString();
28 std::string firstStr = rf.findFile(predictorFile.c_str());
30 setName(moduleName.c_str());
32 handlerPortName =
"/";
33 handlerPortName += getName();
34 handlerPortName +=
"/rpc:i";
36 cntxHomePath = rf.getHomeContextPath().c_str();
38 if (!rpcPort.open(handlerPortName.c_str()))
40 yError() << getName().c_str() <<
" Unable to open port " << handlerPortName.c_str();
48 faceManager =
new FACEManager( moduleName, firstStr, cntxHomePath );
57 bool FACEModule::interruptModule()
64 bool FACEModule::close()
67 yDebug() <<
"starting the shutdown procedure";
68 faceManager->interrupt();
70 yDebug() <<
"deleting thread";
73 yDebug() <<
"done deleting thread";
78 bool FACEModule::updateModule()
84 double FACEModule::getPeriod()
90 bool FACEModule::attach(yarp::os::RpcServer &source)
92 return this->yarp().attachAsServer(source);
96 bool FACEModule::display(
const std::string& element,
const std::string& value)
98 bool returnVal =
false;
100 if (element ==
"landmarks" || element ==
"points" || element ==
"labels" || element ==
"dark-mode")
102 if (element ==
"landmarks")
106 faceManager->displayLandmarks=
true;
109 else if (value==
"off")
111 faceManager->displayLandmarks =
false;
115 yInfo() <<
"error setting value for landmarks";
117 if (element ==
"points")
121 faceManager->displayPoints=
true;
124 else if (value==
"off")
126 faceManager->displayPoints =
false;
130 yInfo() <<
"error setting value for points";
132 if (element ==
"labels")
136 faceManager->displayLabels=
true;
139 else if (value==
"off")
141 faceManager->displayLabels =
false;
145 yInfo() <<
"error setting value for labels";
147 if (element ==
"dark-mode")
151 faceManager->displayDarkMode=
true;
154 else if (value==
"off")
156 faceManager->displayDarkMode =
false;
160 yInfo() <<
"error setting value for darkMode";
167 yInfo() <<
"Error in display request";
173 bool FACEModule::quit()
180 FACEManager::~FACEManager()
185 FACEManager::FACEManager(
const std::string &moduleName,
const std::string &predictorFile,
const std::string &cntxHomePath)
187 yDebug() <<
"initialising Variables";
188 this->moduleName = moduleName;
189 this->predictorFile = predictorFile;
190 this->cntxHomePath = cntxHomePath;
191 yInfo() <<
"contextPATH = " << cntxHomePath.c_str();
195 bool FACEManager::open()
200 inImgPortName =
"/" + moduleName +
"/image:i";
201 BufferedPort<yarp::sig::ImageOf<yarp::sig::PixelRgb> >::open( inImgPortName.c_str() );
203 outImgPortName =
"/" + moduleName +
"/image:o";
204 imageOutPort.open( outImgPortName.c_str() );
206 outTargetPortName =
"/" + moduleName +
"/target:o";
207 targetOutPort.open( outTargetPortName.c_str() );
209 outLandmarksPortName =
"/" + moduleName +
"/landmarks:o";
210 landmarksOutPort.open( outLandmarksPortName.c_str() );
212 yDebug() <<
"path is: " << predictorFile.c_str();
214 faceDetector = dlib::get_frontal_face_detector();
215 dlib::deserialize(predictorFile.c_str()) >> sp;
217 color = cv::Scalar( 0, 255, 0 );
219 displayLandmarks =
true;
220 displayPoints =
false;
221 displayLabels =
false;
222 displayDarkMode =
false;
228 void FACEManager::close()
231 yDebug() <<
"now closing ports...";
232 imageOutPort.writeStrict();
233 imageOutPort.close();
235 targetOutPort.close();
236 landmarksOutPort.close();
237 BufferedPort<yarp::sig::ImageOf<yarp::sig::PixelRgb> >::close();
239 yDebug() <<
"finished closing the read port...";
243 void FACEManager::interrupt()
245 yDebug() <<
"cleaning up...";
246 yDebug() <<
"attempting to interrupt ports";
247 BufferedPort<yarp::sig::ImageOf<yarp::sig::PixelRgb> >::interrupt();
248 yDebug() <<
"finished interrupt ports";
252 void FACEManager::onRead(yarp::sig::ImageOf<yarp::sig::PixelRgb> &img)
255 yarp::sig::ImageOf<yarp::sig::PixelRgb> &outImg = imageOutPort.prepare();
256 yarp::os::Bottle &target=targetOutPort.prepare();
257 yarp::os::Bottle &landmarks=landmarksOutPort.prepare();
261 imgMat = cv::cvarrToMat((IplImage*)img.getIplImage());
267 dlib::array2d<dlib::rgb_pixel> dlibimg;
268 assign_image(dlibimg, dlib::cv_image<dlib::bgr_pixel>(imgMat));
277 std::vector<dlib::rectangle> dets = faceDetector(dlibimg);
279 std::vector<dlib::full_object_detection> shapes;
281 for (
unsigned long j = 0; j < dets.size(); ++j)
283 dlib::full_object_detection shape = sp(dlibimg, dets[j]);
284 shapes.push_back(shape);
287 std::vector<std::pair<int, double >> idTargets;
289 for (
unsigned long i = 0; i < dets.size(); ++i)
291 DLIB_CASSERT(shapes[i].num_parts() == 68,
292 "\t std::vector<image_window::overlay_line> render_face_detections()" 293 <<
"\n\t Invalid inputs were given to this function. " 294 <<
"\n\t dets["<<i<<
"].num_parts(): " << shapes[i].num_parts()
297 const dlib::full_object_detection& d = shapes[i];
300 imgMat.setTo(cv::Scalar(0, 0, 0));
302 if (displayLandmarks)
303 drawLandmarks(imgMat, d);
308 yarp::os::Bottle &landM = landmarks.addList();
309 for (
int f=1; f<shapes[i].num_parts(); f++)
312 if (f != 17 || f != 22 || f != 27 || f != 42 || f != 48)
314 yarp::os::Bottle &temp = landM.addList();
315 temp.addInt(d.part(f).x()/2);
316 temp.addInt(d.part(f).y()/2);
321 if (displayPoints || displayLabels)
323 int pointSize = landmarks.get(0).asList()->size();
327 for (
size_t i = 0; i < pointSize; i++)
329 int pointx = landmarks.get(0).asList()->get(i).asList()->get(0).asInt();
330 int pointy = landmarks.get(0).asList()->get(i).asList()->get(1).asInt();
331 cv::Point center(pointx, pointy);
332 circle(imgMat, center, 3, cv::Scalar(255, 0 , 0), -1, 8);
337 for (
size_t i = 0; i < pointSize; i++)
339 int pointx = landmarks.get(0).asList()->get(i).asList()->get(0).asInt();
340 int pointy = landmarks.get(0).asList()->get(i).asList()->get(1).asInt();
341 cv::Point center(pointx, pointy);
342 std::string s = std::to_string(i);
343 putText(imgMat, s, cvPoint(pointx, pointy), cv::FONT_HERSHEY_COMPLEX_SMALL, 0.6, cvScalar(200,200,250), 1, CV_AA);
349 pt1.x = dets[i].tl_corner().x()/2;
350 pt1.y = dets[i].tl_corner().y()/2;
351 pt2.x = dets[i].br_corner().x()/2;
352 pt2.y = dets[i].br_corner().y()/2;
354 rightEye.x = d.part(42).x()/2 + ((d.part(45).x()/2) - (d.part(42).x()/2))/2;
355 rightEye.y = d.part(43).y()/2 + ((d.part(46).y()/2) - (d.part(43).y()/2))/2;
356 leftEye.x = d.part(36).x()/2 + ((d.part(39).x()/2) - (d.part(36).x()/2))/2;
357 leftEye.y = d.part(38).y()/2 + ((d.part(41).y()/2) - (d.part(38).y()/2))/2;
362 circle(imgMat, leftEye , 2, cv::Scalar( 0, 0, 255 ), -1);
363 circle(imgMat, rightEye , 2, cv::Scalar( 0, 0, 255 ), -1);
365 double areaCalculation =0.0;
366 areaCalculation = (std::fabs(pt2.x-pt1.x)*std::fabs(pt2.y-pt1.y));
368 idTargets.push_back(std::make_pair(i, areaCalculation));
371 if (idTargets.size()>0)
373 std::sort(idTargets.begin(), idTargets.end(), [](
const std::pair<int, double> &left,
const std::pair<int, double> &right) {
374 return left.second > right.second;
378 if (dets.size() > 0 )
380 for (
int i=0; i< idTargets.size(); i++)
383 pt1.x = dets[idTargets[i].first].tl_corner().x()/2;
384 pt1.y = dets[idTargets[i].first].tl_corner().y()/2;
385 pt2.x = dets[idTargets[i].first].br_corner().x()/2;
386 pt2.y = dets[idTargets[i].first].br_corner().y()/2;
407 yarp::os::Bottle &pos = target.addList();
408 pos.addDouble(pt1.x);
409 pos.addDouble(pt1.y);
410 pos.addDouble(pt2.x);
411 pos.addDouble(pt2.y);
413 cv::Point biggestpt1, biggestpt2;
414 biggestpt1.x = dets[idTargets[0].first].tl_corner().x()/2;
415 biggestpt1.y = dets[idTargets[0].first].tl_corner().y()/2;
416 biggestpt2.x = dets[idTargets[0].first].br_corner().x()/2;
417 biggestpt2.y = dets[idTargets[0].first].br_corner().y()/2;
419 rectangle(imgMat, biggestpt1, biggestpt2, cv::Scalar( 0, 255, 0 ), 1, 8, 0);
421 targetOutPort.write();
422 if (landmarksOutPort.getOutputCount()>0)
423 landmarksOutPort.write();
427 IplImage yarpImg = imgMat;
428 outImg.resize(yarpImg.width, yarpImg.height);
429 cvCopy( &yarpImg, (IplImage *) outImg.getIplImage());
431 imageOutPort.write();
436 void FACEManager::drawLandmarks(cv::Mat &mat,
const dlib::full_object_detection &d)
439 for (
unsigned long i = 1; i <= 16; ++i)
440 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
443 for (
unsigned long i = 18; i <= 21; ++i)
444 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
447 for (
unsigned long i = 23; i <= 26; ++i)
448 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
451 for (
unsigned long i = 28; i <= 30; ++i)
452 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
455 line(mat, cv::Point(d.part(30).x()/2, d.part(30).y()/2), cv::Point(d.part(35).x()/2, d.part(35).y()/2), color);
456 for (
unsigned long i = 31; i <= 35; ++i)
457 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
460 for (
unsigned long i = 37; i <= 41; ++i)
461 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
462 line(mat, cv::Point(d.part(36).x()/2, d.part(36).y()/2), cv::Point(d.part(41).x()/2, d.part(41).y()/2), color);
465 for (
unsigned long i = 43; i <= 47; ++i)
466 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
467 line(mat, cv::Point(d.part(42).x()/2, d.part(42).y()/2), cv::Point(d.part(47).x()/2, d.part(47).y()/2), color);
470 for (
unsigned long i = 49; i <= 59; ++i)
471 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);
472 line(mat, cv::Point(d.part(48).x()/2, d.part(48).y()/2), cv::Point(d.part(59).x()/2, d.part(59).y()/2), color);
475 line(mat, cv::Point(d.part(60).x()/2, d.part(60).y()/2), cv::Point(d.part(67).x()/2, d.part(67).y()/2), color);
476 for (
unsigned long i = 61; i <= 67; ++i)
477 line(mat, cv::Point(d.part(i).x()/2, d.part(i).y()/2), cv::Point(d.part(i-1).x()/2, d.part(i-1).y()/2), color);