20 #include <yarp/math/Rand.h>
21 #include <yarp/math/Math.h>
22 #include <yarp/cv/Cv.h>
23 #include "iCub/module.h"
27 using namespace yarp::os;
28 using namespace yarp::sig;
29 using namespace yarp::math;
30 using namespace yarp::cv;
34 bool Manager::configure(ResourceFinder &rf)
36 name=rf.find(
"name").asString();
39 motionFeatures.open(
"/"+name+
"/motionFilter:i");
42 toolPoint.open(
"/"+name+
"/target:o");
43 imgOutPort.open(
"/"+name+
"/img:o");
46 rpcHuman.open(
"/"+name+
"/human:rpc");
48 motionFeatures.setManager(
this);
49 lineDetails =
new lineData [10];
54 bool Manager::interruptModule()
56 motionFeatures.interrupt();
57 toolPoint.interrupt();
58 imgOutPort.interrupt();
66 motionFeatures.close();
73 int Manager::processHumanCmd(
const Bottle &cmd, Bottle &b)
75 int ret=Vocab::encode(cmd.get(0).asString());
79 if (cmd.get(1).isList())
80 b=*cmd.get(1).asList();
87 bool Manager::updateModule()
92 Bottle cmd, val, reply;
93 rpcHuman.read(cmd,
true);
94 int rxCmd=processHumanCmd(cmd,val);
95 if (rxCmd==Vocab::encode(
"action"))
97 reply.addString(
"ack");
98 rpcHuman.reply(reply);
103 double Manager::getPeriod()
109 void Manager::processMotionPoints(Bottle &b)
112 cv::Mat imgMat(Size(320,240),CV_8UC3);
113 cv::Mat imgClean(Size(320,240),CV_8UC3);
114 imgMat = Scalar::all(0);
115 imgClean = Scalar::all(255);
117 for (
int x=1; x<b.size(); x++)
120 pt.x = b.get(x).asList()->get(0).asInt();
121 pt.y = b.get(x).asList()->get(1).asInt();
122 imgMat.at<cv::Vec3b>(pt.y,pt.x)[0] = 255 ;
123 imgMat.at<cv::Vec3b>(pt.y,pt.x)[1] = 0 ;
124 imgMat.at<cv::Vec3b>(pt.y,pt.x)[2] = 0 ;
125 imgClean.at<cv::Vec3b>(pt.y,pt.x)[0] = 255 ;
126 imgClean.at<cv::Vec3b>(pt.y,pt.x)[1] = 0 ;
127 imgClean.at<cv::Vec3b>(pt.y,pt.x)[2] = 0 ;
131 int an = n > 0 ? n : -n;
132 int element_shape = MORPH_RECT;
133 Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
134 morphologyEx(imgMat, imgMat, CV_MOP_CLOSE, element);
137 data = processImage(b, imgMat, imgClean, lineDetails);
140 processBlobs(data, imgClean, lineDetails);
142 ImageOf<PixelRgb> &outImg = imgOutPort.prepare();
143 outImg.resize( imgClean.cols, imgClean.rows );
144 imgClean.copyTo(toCvMat(outImg));
149 void Manager::processBlobs(Bottle &b, cv::Mat &dest, lineData *lineDetails)
151 int sampleCount = b.size();
153 int clusterCount = 2;
154 Mat points(sampleCount, dimensions, CV_32F);
156 Mat centers(clusterCount, dimensions, points.type());
157 for(
int i = 0; i<sampleCount;i++)
159 points.at<
float>(i,0) = (
float) b.get(i).asList()->get(0).asInt();
160 points.at<
float>(i,1) = (
float) b.get(i).asList()->get(1).asInt();
163 if (sampleCount<clusterCount)
165 printf(
"sampleCount < clusterCount!\n");
169 kmeans(points, clusterCount, labels, TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);
172 for (
int i = 0; i < clusterCount; i++)
174 int clusterIdx = labels.at<
int>(i);
176 ipt.x = (int) centers.at<
float>(i,0);
177 ipt.y = (int) centers.at<
float>(i,1);
180 circle( dest, ipt, 5, CV_RGB(255,255,255), cv::FILLED, cv::LINE_AA );
183 double intercept = 0;
185 if (pts[1].y < pts[0].y )
187 double pow1 = pow( fabs((
double)pts[0].x - (
double)pts[1].x),2);
188 double pow2 = pow( fabs((
double)pts[0].y - (
double)pts[1].y),2);
189 double lenAB = sqrt( pow1 + pow2 );
191 endPoint.x = (int)(pts[1].x + (
double)(pts[1].x - pts[0].x) / lenAB * 50);
192 endPoint.y = (int)(pts[1].y + (
double) (pts[1].y - pts[0].y) / lenAB * 50);
193 line(dest, pts[0], endPoint, Scalar(0,0,0), 2, cv::LINE_AA);
194 gradient = (double)( endPoint.y - pts[0].y ) / (double)( endPoint.x - pts[0].x );
195 intercept = (double)( pts[0].y - (
double)(pts[0].x * gradient) );
196 lineDetails[1].gradient = gradient;
197 lineDetails[1].intercept = intercept;
201 double pow1 = pow( fabs((
double)pts[1].x - (
double)pts[0].x), 2);
202 double pow2 = pow( fabs((
double)pts[1].y - (
double)pts[0].y), 2);
203 double lenAB = sqrt( pow1 + pow2 );
205 endPoint.x = (int)(pts[0].x + (
double)(pts[0].x - pts[1].x) / lenAB * 50);
206 endPoint.y = (int)(pts[0].y + (
double)(pts[0].y - pts[1].y) / lenAB * 50);
207 line(dest, pts[1], endPoint, Scalar(0,0,0), 2, cv::LINE_AA);
209 gradient = (double)( endPoint.y - pts[1].y) / (double)(endPoint.x - pts[1].x);
210 intercept = (double)( endPoint.y - (
double)(endPoint.x * gradient) );
211 lineDetails[1].gradient = gradient;
212 lineDetails[1].intercept = intercept;
215 getIntersection(dest, lineDetails);
218 void Manager::getIntersection(cv::Mat &dest, lineData *lineDetails)
224 intersect.x = (int)( (lineDetails[1].intercept - lineDetails[0].intercept) / (lineDetails[0].gradient-lineDetails[1].gradient));
225 intersect.y = (int)( (lineDetails[0].gradient * intersect.x) + lineDetails[0].intercept);
227 if (intersect.x > 0 && intersect.y >0 && intersect.x < dest.cols && intersect.y < dest.rows)
229 circle( dest, intersect, dest.rows/(
int)32.0, Scalar( 255, 0, 0 ), thickness, lineType );
232 output.addInt(intersect.x);
233 output.addInt(intersect.y);
234 toolPoint.write(output);
239 Bottle Manager::processImage(Bottle &b, cv::Mat &dest, cv::Mat &clean, lineData *lineDetails)
241 Bottle botListDel, botPointsDel;
242 Bottle correctList, correctElements;
243 vector<vector<Point> > contours;
244 cv::Mat imgGray(Size(320,240),CV_8UC1);
245 cv::cvtColor( dest, imgGray, CV_RGB2GRAY);
247 double intercept = 0;
248 findContours(imgGray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
249 for(
size_t i = 0; i < contours.size(); i++)
251 size_t count = contours[i].size();
256 Mat(contours[i]).convertTo(pointsf, CV_32F);
257 RotatedRect box = fitEllipse(pointsf);
259 if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 )
262 double area = contourArea( Mat(contours[i]) );
263 if ( area > 10 && area < 4000)
265 for (
int x = (
int)box.center.x - (
int)box.size.width; x < (
int)box.center.x + (
int)box.size.width; x++){
266 for (
int y = (
int)box.center.y - (
int)box.size.height; y < (
int)box.center.y + (
int)box.size.height; y++)
268 if (y< imgGray.rows-1 && x< imgGray.cols-1 && y > 0 && x > 0)
270 if( dest.at<cv::Vec3b>(y,x)[0] == 255 )
272 dest.at<cv::Vec3b>(y,x)[0] = 0;
273 botPointsDel.clear();
274 botPointsDel.addInt(x);
275 botPointsDel.addInt(y);
276 botListDel.addList() = botPointsDel;
284 for (
int v = 1; v<b.size(); v++)
287 for (
int w = 0; w<botListDel.size(); w++)
289 if ( ((
float) b.get(v).asList()->get(0).asInt() == botListDel.get(w).asList()->get(0).asInt() ) &&
290 ((float) b.get(v).asList()->get(1).asInt() == botListDel.get(w).asList()->get(1).asInt() ) )
297 correctList.addList() = *b.get(v).asList();
299 drawContours(dest, contours, (
int)i, Scalar::all(255), 1, 8);
304 if ( vtx[1].y < vtx[3].y )
307 fprintf(stdout,
"3 < 0 %lf smaller than %lf \n", vtx[3].y, vtx[1].y);
312 fprintf(stdout,
"0 < 3 %lf smaller than %lf \n", vtx[1].y, vtx[3].y);
315 line(clean, vtx[j], vtx[(j+1)%4], Scalar(0,0,0), 2, cv::LINE_AA);
316 gradient = ( vtx[(j+1)%4].y - vtx[j].y) / (vtx[(j+1)%4].x - vtx[j].x);
317 intercept = ( vtx[j].y - (vtx[j].x *gradient) );
319 lineDetails[0].gradient = gradient;
320 lineDetails[0].intercept = intercept;