18 #include <opencv2/core.hpp>
19 #include <yarp/cv/Cv.h>
20 #include "lbpExtract.h"
22 using namespace yarp::sig;
23 using namespace yarp::cv;
26 bool SEGMENTModule::configure(yarp::os::ResourceFinder &rf){
27 moduleName = rf.check(
"name", yarp::os::Value(
"lbpExtract"),
"module name (string)").asString();
29 setName(moduleName.c_str());
31 handlerPortName =
"/";
32 handlerPortName += getName();
33 handlerPortName +=
"/rpc:i";
35 if (!rpcPort.open(handlerPortName)) {
36 fprintf(stdout,
"%s : Unable to open port %s\n", getName().c_str(), handlerPortName.c_str());
44 segmentManager =
new SEGMENTManager( moduleName );
46 int rad = rf.check(
"radius",yarp::os::Value(5)).asInt32();
47 int iter = rf.check(
"numIteration",yarp::os::Value(5)).asInt32();
48 int neigh = rf.check(
"neighbours",yarp::os::Value(8)).asInt32();
49 int topB = rf.check(
"topBound",yarp::os::Value(40)).asInt32();
50 int minL = rf.check(
"minArcLength",yarp::os::Value(75)).asInt32();
51 int maxL = rf.check(
"maxArcLength",yarp::os::Value(1000)).asInt32();
52 int minA = rf.check(
"minArea",yarp::os::Value(300)).asInt32();
53 int maxA = rf.check(
"maxArea",yarp::os::Value(6000)).asInt32();
54 int minW = rf.check(
"minWidth",yarp::os::Value(3)).asInt32();
56 segmentManager->setDefaultValues(rad, neigh, topB, minL, maxL, iter, minA, maxA, minW);
59 segmentManager->open();
65 bool SEGMENTModule::interruptModule(){
71 bool SEGMENTModule::close(){
73 yDebug(
"starting the shutdown procedure\n");
74 segmentManager->interrupt();
75 segmentManager->close();
76 yDebug(
"deleting thread\n");
77 delete segmentManager;
78 yDebug(
"done deleting thread\n");
83 bool SEGMENTModule::attach(yarp::os::RpcServer &source){
84 return this->yarp().attachAsServer(source);
88 bool SEGMENTModule::quit(){
94 bool SEGMENTModule::reset(){
100 bool SEGMENTModule::updateModule(){
105 double SEGMENTModule::getPeriod(){
110 bool SEGMENTModule::setRadius(
const int32_t radius){
111 segmentManager->setRadius(radius);
116 bool SEGMENTModule::setNeighbours(
const int32_t neighbours){
117 segmentManager->setNeighbours(neighbours);
122 bool SEGMENTModule::setTopBound(
const int32_t topBound){
123 segmentManager->setTopBound(topBound);
128 bool SEGMENTModule::setMinArcLength(
const int32_t minArcLenght){
129 segmentManager->setMinArcLength(minArcLenght);
134 bool SEGMENTModule::setMaxArcLength(
const int32_t maxArcLenght){
135 segmentManager->setMaxArcLength(maxArcLenght);
140 bool SEGMENTModule::setMinArea(
const int32_t minArea){
141 segmentManager->setMinArea(minArea);
146 bool SEGMENTModule::setMaxArea(
const int32_t maxArea){
147 segmentManager->setMaxArea(maxArea);
152 bool SEGMENTModule::setMinWidth(
const int32_t minWidth){
153 segmentManager->setMinWidth(minWidth);
158 bool SEGMENTModule::setNumIteration(
const int32_t numIteration){
159 segmentManager->setNumIteration(numIteration);
164 bool SEGMENTModule::setbbOffset(
const int32_t offset){
165 segmentManager->setbbOffset(offset);
170 bool SEGMENTModule::resetAllValues(){
172 segmentManager->resetAllValues();
177 bool SEGMENTModule::verbosity(
const int32_t verbose){
179 if (verbose <0 && verbose > 1)
183 segmentManager->verbosity(verbose);
190 int SEGMENTModule::getRadius(){
191 return segmentManager->getRadius();
195 int SEGMENTModule::getNeighbours(){
196 return segmentManager->getNeighbours();
200 int SEGMENTModule::getTopBound(){
201 return segmentManager->getTopBound();
205 int SEGMENTModule::getMinArcLength(){
206 return segmentManager->getMinArcLength();
210 int SEGMENTModule::getMaxArcLength(){
211 return segmentManager->getMaxArcLength();
215 int SEGMENTModule::getMinArea(){
216 return segmentManager->getMinArea();
220 int SEGMENTModule::getMaxArea(){
221 return segmentManager->getMaxArea();
225 int SEGMENTModule::getMinWidth(){
226 return segmentManager->getMinWidth();
230 int SEGMENTModule::getNumIteration(){
231 return segmentManager->getNumIteration();
235 int SEGMENTModule::getbbOffset(){
236 return segmentManager->getbbOffset();
240 yarp::os::Bottle SEGMENTModule::get_component_around(
const int32_t x,
const int32_t y){
241 return segmentManager->get_component_around(x, y);
245 SEGMENTManager::~SEGMENTManager(){
250 SEGMENTManager::SEGMENTManager(
const std::string &moduleName ){
251 fprintf(stdout,
"initialising Variables\n");
252 this->moduleName = moduleName;
256 bool SEGMENTManager::setDefaultValues(
const int32_t radius,
const int32_t neighbours,
const int32_t topBound,
const int32_t minArcLength,
const int32_t maxArcLength,
const int32_t numIteration,
const int32_t minArea,
const int32_t maxArea,
const int32_t minWidth){
258 defaultRadius = radius;
259 defaultNeighbours = neighbours;
260 defaultTopBound = topBound;
261 defaultMinArcLength = minArcLength;
262 defaultMaxArcLength = maxArcLength;
263 defaultNumIteration = numIteration;
264 defaultMinArea = minArea;
265 defaultMaxArea = maxArea;
266 defaultMinWidth = minWidth;
272 bool SEGMENTManager::open(){
276 inPortName =
"/" + moduleName +
"/image:i";
277 BufferedPort<ImageOf<PixelRgb> >::open( inPortName );
279 outPortPropagate.open(
"/" + moduleName +
"/propagated:o" );
280 outPortBlobs.open(
"/" + moduleName +
"/extractedlbp:o" );
281 outPortSegmented.open(
"/" + moduleName +
"/segmentedlbp:o" );
282 outTargetPort.open(
"/" + moduleName +
"/blobs:o" );
283 outPortLbp.open(
"/" + moduleName +
"/lbp:o" );
284 outPortLbpContours.open(
"/" + moduleName +
"/contourslbp:o" );
286 radius = defaultRadius;
287 neighbours = defaultNeighbours;
288 minArcLength = defaultMinArcLength;
289 maxArcLength = defaultMaxArcLength;
290 topBound = defaultTopBound;
291 numIteration = defaultNumIteration;
293 minArea = defaultMinArea;
294 maxArea = defaultMaxArea;
296 minWidth = defaultMinWidth;
302 yInfo(
"Module started with the following default values:\nradius: %d, neighbours %d, minArcLength %d, maxArcLength %d, minArea %d, maxArea %d, minWidth %d, topBound %d, numIteration %d", radius, neighbours, minArcLength, maxArcLength, minArea, maxArea, minWidth, topBound, numIteration);
308 void SEGMENTManager::close(){
310 yDebug(
"now closing ports...\n");
312 outPortPropagate.close();
313 outPortBlobs.close();
314 outPortSegmented.close();
316 outPortLbpContours.close();
317 outTargetPort.close();
319 BufferedPort<ImageOf<PixelRgb> >::close();
321 yDebug(
"finished closing the read port...\n");
325 void SEGMENTManager::interrupt(){
326 yDebug(
"cleaning up...\n");
327 yDebug(
"attempting to interrupt ports\n");
328 BufferedPort<ImageOf<PixelRgb> >::interrupt();
330 yDebug(
"finished interrupt ports\n");
334 bool SEGMENTManager::setRadius(
const int32_t radius){
335 this->radius = radius;
340 bool SEGMENTManager::setNeighbours(
const int32_t neighbours){
341 this->neighbours = neighbours;
346 bool SEGMENTManager::setTopBound(
const int32_t topBound){
347 this->topBound = topBound;
352 bool SEGMENTManager::setMinArcLength(
const int32_t minArcLength){
353 this->minArcLength = minArcLength;
358 bool SEGMENTManager::setMaxArcLength(
const int32_t maxArcLength){
359 this->maxArcLength = maxArcLength;
364 bool SEGMENTManager::setMinArea(
const int32_t minArea){
365 this->minArea = minArea;
370 bool SEGMENTManager::setMaxArea(
const int32_t maxArea){
371 this->maxArea = maxArea;
376 bool SEGMENTManager::setMinWidth(
const int32_t minWidth){
377 this->minWidth = minWidth;
382 bool SEGMENTManager::setNumIteration(
const int32_t numIteration){
383 this->numIteration = numIteration;
388 bool SEGMENTManager::setbbOffset(
const int32_t offset){
389 this->bbOffset = offset;
394 bool SEGMENTManager::resetAllValues(){
395 radius = defaultRadius;
396 neighbours = defaultNeighbours;
397 topBound = defaultTopBound;
398 minArcLength = defaultMinArcLength;
399 maxArcLength = defaultMaxArcLength;
400 minArea = defaultMinArea;
401 maxArea = defaultMaxArea;
402 minWidth = defaultMinWidth;
408 bool SEGMENTManager::verbosity(
const int32_t verbose)
410 this->verbose = verbose;
415 int SEGMENTManager::getRadius(){
420 int SEGMENTManager::getNeighbours(){
421 return this->neighbours;
425 int SEGMENTManager::getTopBound(){
426 return this->topBound;
430 int SEGMENTManager::getMinArcLength(){
431 return this->minArcLength;
435 int SEGMENTManager::getMaxArcLength(){
436 return this->maxArcLength;
440 int SEGMENTManager::getMinArea(){
441 return this->minArea;
445 int SEGMENTManager::getMaxArea(){
446 return this->maxArea;
450 int SEGMENTManager::getMinWidth(){
451 return this->minWidth;
455 int SEGMENTManager::getNumIteration(){
456 return this->numIteration;
460 int SEGMENTManager::getbbOffset(){
461 return this->bbOffset;
466 yarp::os::Bottle SEGMENTManager::get_component_around(
const int32_t x,
const int32_t y){
468 yarp::os::Bottle& tosend = getComponents(segmented, x, y);
474 yarp::os::Bottle& SEGMENTManager::getComponents(cv::Mat &img,
int x,
int y)
478 std::vector<std::vector<cv::Point> > objcnt;
479 std::vector<cv::Vec4i> objhrch;
483 if (img.rows == 0 || img.cols == 0){
487 cvtColor(img, prov, CV_BGR2GRAY);
489 findContours( prov, objcnt, objhrch, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE );
493 cv::Mat nonZeroCoordinates;
494 cv::Mat inside = cv::Mat::zeros( imgMat.size(), CV_8UC1 );
496 for(
size_t i = 0; i< objcnt.size(); i++ )
498 if (pointPolygonTest( objcnt[i], cv::Point2f(x, y), 1 ) > 0)
499 cv::drawContours( inside, objcnt, i, cvScalar(255,255,355), cv::FILLED, 8, objhrch, 0, cv::Point() );
502 cv::findNonZero(inside, nonZeroCoordinates);
504 for (
size_t i = 0; i < nonZeroCoordinates.total(); i++ ) {
505 yarp::os::Bottle &subjList = allPoints.addList();
506 subjList.addInt32(nonZeroCoordinates.at<cv::Point>(i).x);
507 subjList.addInt32(nonZeroCoordinates.at<cv::Point>(i).y);
513 void SEGMENTManager::onRead(ImageOf<yarp::sig::PixelRgb> &img){
516 ImageOf<PixelRgb> &outOrig = outPortPropagate.prepare();
517 ImageOf<PixelRgb> &outImg = outPortBlobs.prepare();
518 ImageOf<PixelRgb> &outSeg = outPortSegmented.prepare();
519 ImageOf<PixelMono> &outLbp = outPortLbp.prepare();
520 ImageOf<PixelMono> &outLbpContour = outPortLbpContours.prepare();
522 outOrig.resize(img.width(), img.height());
523 outImg.resize(img.width(), img.height());
524 outSeg.resize(img.width(), img.height());
525 outLbp.resize(img.width(), img.height());
526 outLbpContour.resize(img.width(), img.height());
532 outLbpContour.zero();
534 imgMat = toCvMat(img);
536 yarp::os::Bottle &b = outTargetPort.prepare();
540 cv::Mat
lbp = cv::Mat::zeros( imgMat.size(), CV_8UC1 );
541 cv::Mat extracted = cv::Mat::zeros( imgMat.size(), CV_8UC3 );
544 segmented = cv::Mat::zeros( imgMat.size(), CV_8UC3 );
546 cvtColor(imgMat, temp, CV_BGR2GRAY);
550 lbp::VARLBP(temp,
lbp, radius, neighbours);
557 normalize(
lbp, norm, 0, 255, cv::NORM_MINMAX, CV_8UC1);
559 uint8_t* pixelPtr = (uint8_t*)norm.data;
560 int cn = norm.channels();
561 for(
int i = 0; i < norm.rows; i++){
562 for(
int j = 0; j < norm.cols; j += cn){
563 cv::Scalar_<uint8_t> bgrPixel;
564 bgrPixel.val[0] = pixelPtr[i*norm.cols*cn + j*cn + 0];
566 if (bgrPixel.val[0] < 255 && bgrPixel.val[0] > 5)
567 pixelPtr[i*norm.cols*cn + j*cn + 0] = 255;
569 pixelPtr[i*norm.cols*cn + j*cn + 0] = 0;
574 cleanedImg = norm.clone();
576 std::vector<std::vector<cv::Point> > cnt;
577 std::vector<cv::Vec4i> hrch;
579 cv::Mat structuringElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
580 cv::morphologyEx( cleanedImg, cleanedImg, cv::MORPH_CLOSE, structuringElement );
585 findContours( cleanedImg, cnt, hrch, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_L1 );
586 cv::fillPoly( cleanedImg, cnt, 255);
587 structuringElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2*radius-1, 2*radius-1));
588 cv::morphologyEx( cleanedImg, cleanedImg, cv::MORPH_ERODE, structuringElement );
594 findContours( cleanedImg, cnt, hrch, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_L1 );
595 cv::fillPoly( cleanedImg, cnt, 255);
596 structuringElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(minWidth, minWidth));
597 cv::morphologyEx( cleanedImg, cleanedImg, cv::MORPH_OPEN, structuringElement );
601 findContours( cleanedImg, cnt, hrch, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_L1 );
604 int alignOffsetX = (imgMat.cols - cleanedImg.cols) / 2;
605 int alignOffsetY = (imgMat.rows - cleanedImg.rows) / 2;
606 for(
size_t i = 0; i < cnt.size(); i++ )
608 for(
size_t j = 0; j < cnt[i].size(); j++ )
610 cnt[i][j].x += alignOffsetX;
611 cnt[i][j].y += alignOffsetY;
616 std::vector<cv::Moments> mu(cnt.size() );
617 for(
size_t i = 0; i < cnt.size(); i++ )
618 mu[i] = moments( cnt[i],
false );
621 std::vector<cv::Point2f> mc( cnt.size() );
623 for(
size_t i = 0; i < cnt.size(); i++ )
624 mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
626 std::vector<std::vector<cv::Point> > contours_poly( cnt.size() );
627 std::vector<cv::Rect> boundRect( cnt.size() );
629 for(
size_t i = 0; i< cnt.size(); i++ ){
631 double length = arcLength( cnt[i],
true );
632 double area = contourArea(cnt[i]);
634 if ( (mc[i].y > topBound) && (length > minArcLength) && (length < maxArcLength) && (area > minArea) && (area < maxArea)){
639 yDebug(
" Contour[%zu] -X[%lf] -Y[%lf] -Length: %.2f -Area %lf", i, mc[i].x, mc[i].y, length, area);
640 cv::drawContours( extracted, cnt, i, cvScalar(255,0,0), 2, 8, hrch, 0, cv::Point() );
643 approxPolyDP( cv::Mat(cnt[i]), contours_poly[i], 3,
true );
644 boundRect[i] = boundingRect( cv::Mat(contours_poly[i]) );
652 double topLeftX = boundRect[i].tl().x;
653 double topLeftY = boundRect[i].tl().y;
654 double bottomRightX = boundRect[i].br().x;
655 double bottomRightY = boundRect[i].br().y;
659 if (topLeftX > shift)
662 if (topLeftY > shift)
665 if (bottomRightX > 0 && bottomRightX < (img.width() - shift))
666 bottomRightX += shift;
668 if (bottomRightY > 0 && bottomRightY < (img.height() - shift))
669 bottomRightY += shift;
673 int blobWidth = std::abs(bottomRightX - topLeftX);
674 int blobHeight = std::abs(bottomRightY - topLeftY);
678 cv::Rect roi(topLeftX, topLeftY, blobWidth, blobHeight);
680 if (blobWidth > 20 && blobHeight > 20){
683 cv::Mat image_roi(imgMat, roi);
687 rect = cv::Rect( border, border, image_roi.cols - (border*2), image_roi.rows-(border*2));
690 cv::Mat bgModel,fgModel;
693 cv::grabCut(image_roi, result, rect, bgModel, fgModel, numIteration, cv::GC_INIT_WITH_RECT);
696 cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
699 cv::Mat foreground(image_roi.size(),CV_8UC3,cv::Scalar(0,0,0));
700 image_roi.copyTo(foreground,result);
703 foreground.copyTo(segmented(cv::Rect(topLeftX, topLeftY, foreground.cols, foreground.rows)));
708 std::vector<std::vector<cv::Point> > objcnt;
709 std::vector<cv::Vec4i> objhrch;
711 cvtColor(segmented, prov, CV_BGR2GRAY);
712 findContours( prov, objcnt, objhrch, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE );
715 std::vector<cv::Moments> muSeg(objcnt.size() );
716 for(
size_t i = 0; i < objcnt.size(); i++ )
717 muSeg[i] = moments( objcnt[i],
false );
720 std::vector<cv::Point2f> mcSeg( objcnt.size() );
722 for(
size_t i = 0; i < objcnt.size(); i++ )
723 mcSeg[i] = cv::Point2f( muSeg[i].m10/muSeg[i].m00 , muSeg[i].m01/muSeg[i].m00 );
725 std::vector<std::vector<cv::Point> > contours_polySeg( objcnt.size() );
726 std::vector<cv::Rect> boundRectSeg( objcnt.size() );
728 for(
size_t i = 0; i< objcnt.size(); i++ ){
730 double area = contourArea(objcnt[i]);
734 cv::drawContours( extracted, objcnt, i, cvScalar(255,255,255), cv::FILLED, 8, objhrch, 0, cv::Point() );
736 approxPolyDP( cv::Mat(objcnt[i]), contours_polySeg[i], 3,
true );
737 boundRectSeg[i] = boundingRect( cv::Mat(contours_polySeg[i]) );
739 yarp::os::Bottle &t=b.addList();
744 double topLeftX = boundRectSeg[i].tl().x - bbOffset;
745 double topLeftY = boundRectSeg[i].tl().y - bbOffset;
746 double bottomRightX = boundRectSeg[i].br().x + bbOffset;
747 double bottomRightY = boundRectSeg[i].br().y + bbOffset;
749 yDebug(
"%lf %lf %lf %lf \n", topLeftX, topLeftY, bottomRightX, bottomRightY);
753 if (topLeftX < shift)
756 if (topLeftY < shift)
759 if (bottomRightX > img.width()-3)
760 bottomRightX = img.width()-3;
762 if (bottomRightY > img.height()-3)
763 bottomRightY = img.height()-3;
765 t.addFloat64(topLeftX);
766 t.addFloat64(topLeftY);
767 t.addFloat64(bottomRightX);
768 t.addFloat64(bottomRightY);
787 outTargetPort.write();
789 outOrig.resize(imgMat.size().width, imgMat.size().height);
790 outOrig = fromCvMat<PixelRgb>(imgMat);
791 outPortPropagate.setEnvelope(ts);
792 outPortPropagate.write();
794 outImg.resize(extracted.size().width, extracted.size().height);
795 outImg = fromCvMat<PixelRgb>(extracted);
796 outPortBlobs.setEnvelope(ts);
797 outPortBlobs.write();
799 outSeg.resize(segmented.size().width, segmented.size().height);
800 outSeg = fromCvMat<PixelRgb>(segmented);
801 outPortSegmented.setEnvelope(ts);
802 outPortSegmented.write();
805 cvtColor(imgMat, tmp, CV_BGR2GRAY);
806 lbp::OLBP(tmp, olbp);
807 normalize(olbp, olbp, 0, 255, cv::NORM_MINMAX, CV_8UC1);
809 outLbpContour.resize(norm.size().width, norm.size().height);
810 outLbpContour = fromCvMat<PixelMono>(norm);
811 outPortLbpContours.setEnvelope(ts);
812 outPortLbpContours.write();
814 outLbp.resize(olbp.size().width, olbp.size().height);
815 outLbp = fromCvMat<PixelMono>(olbp);
816 outPortLbp.setEnvelope(ts);
Original code by philipp <bytefish[at]gmx[dot]de>