00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Robots/Beobot2/HumanRobotInteraction/FaceDetector.H"
00039 #include "Ice/BeobotEvents.ice.H"
00040
00041 #include "Raster/Raster.H"
00042 #include "Util/sformat.H"
00043 #include "Image/Image.H"
00044 #include "Ice/IceImageUtils.H"
00045
00046 #include <sys/stat.h>
00047
00048
00049
00050
00051 FaceDetector::FaceDetector(OptionManager& mgr,
00052 const std::string& descrName, const std::string& tagName) :
00053 RobotBrainComponent(mgr, descrName, tagName),
00054 itsOfs(new OutputFrameSeries(mgr)),
00055 itsTimer(1000000),
00056 itsCurrImgID(-1),
00057 itsPrevProcImgID(-1)
00058 {
00059 addSubComponent(itsOfs);
00060 }
00061
00062
00063 FaceDetector::~FaceDetector()
00064 { }
00065
00066
00067 void FaceDetector::start1()
00068 {
00069
00070 itsTimer.reset();
00071 }
00072
00073
00074
00075 void FaceDetector::registerTopics()
00076 {
00077
00078 this->registerSubscription("CameraMessageTopic");
00079
00080 this->registerPublisher("FacesMessageTopic");
00081 }
00082
00083
00084 void FaceDetector::evolve()
00085 {
00086
00087 its_Curr_Img_mutex.lock();
00088 bool newImageFlag = (itsPrevProcImgID < itsCurrImgID);
00089 its_Curr_Img_mutex.unlock();
00090
00091
00092 if(newImageFlag)
00093 {
00094 itsTimer.reset();
00095
00096 its_Curr_Img_mutex.lock();
00097 itsProcImg = itsCurrImg;
00098 itsPrevProcImgID = itsCurrImgID;
00099 its_Curr_Img_mutex.unlock();
00100
00101
00102 Image<PixRGB<byte> > res = findFaces(itsProcImg);
00103
00104
00105 itsOfs->writeRGB(res, "display");
00106 itsOfs->updateNext();
00107 LINFO("time: %15.3f", itsTimer.get()/1000.0);
00108
00109
00110 BeobotEvents::FacesMessagePtr msg =
00111 new BeobotEvents::FacesMessage;
00112 msg->RequestID = itsPrevProcImgID;
00113
00114 its_Curr_Res_mutex.lock();
00115 LINFO("Number of faces detected : %"ZU, itsCurrentFacesFound.size());
00116 for(uint i = 0; i < itsCurrentFacesFound.size(); i++)
00117 {
00118 ImageIceMod::RectangleIce rect;
00119 rect.tl.i = itsCurrentFacesFound[i].top();
00120 rect.tl.j = itsCurrentFacesFound[i].left();
00121 rect.br.i = itsCurrentFacesFound[i].bottomO();
00122 rect.br.j = itsCurrentFacesFound[i].rightO();
00123 msg->faces.push_back(rect);
00124 LINFO("[%3d,%3d,%3d,%3d]", rect.tl.i,rect.tl.j,rect.br.i,rect.br.j );
00125 }
00126 its_Curr_Res_mutex.unlock();
00127
00128
00129 LINFO("[%6d] Publishing Faces Message", itsCurrMessageID++);
00130 publish("FacesMessageTopic", msg);
00131 }
00132 }
00133
00134
00135 void FaceDetector::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00136 const Ice::Current&)
00137 {
00138
00139
00140
00141 if(eMsg->ice_isA("::BeobotEvents::CameraMessage"))
00142 {
00143
00144 BeobotEvents::CameraMessagePtr cameraMsg =
00145 BeobotEvents::CameraMessagePtr::dynamicCast(eMsg);
00146
00147 int currRequestID = cameraMsg->RequestID;
00148 LINFO("Got a CameraMessage with Request ID = %d",
00149 currRequestID);
00150 Image<PixRGB<byte> > ima = Ice2Image<PixRGB<byte> >(cameraMsg->image);
00151
00152
00153 its_Curr_Img_mutex.lock();
00154 itsCurrImg = ima;
00155 itsCurrImgID = cameraMsg->RequestID;
00156 its_Curr_Img_mutex.unlock();
00157
00158 LINFO("time: %15.3f", itsTimer.get()/1000.0);
00159 }
00160 }
00161
00162
00163 Image<PixRGB<byte> > FaceDetector::findFaces(Image<PixRGB<byte> > ima)
00164 {
00165 Image<PixRGB<byte> > res;
00166 IplImage *img = img2ipl(ima);
00167
00168
00169 int scale = 1;
00170
00171
00172 const char* cascade_name =
00173 "haarcascade_frontalface_alt.xml";
00174
00175
00176 CvHaarClassifierCascade* cascade =
00177 (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
00178
00179
00180
00181 if( !cascade )
00182 LFATAL("ERROR: Could not load classifier cascade");
00183
00184
00185 IplImage* temp =
00186 cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );
00187
00188
00189 CvPoint pt1, pt2;
00190 int i;
00191
00192
00193 CvMemStorage* storage = 0;
00194 storage = cvCreateMemStorage(0);
00195 cvClearMemStorage( storage );
00196
00197 std::vector<Rectangle> tempResults;
00198
00199
00200 if( cascade )
00201 {
00202
00203
00204
00205
00206 CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
00207 1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
00208 cvSize(40, 40) );
00209
00210
00211 for( i = 0; i < (faces ? faces->total : 0); i++ )
00212 {
00213
00214 CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
00215
00216
00217 pt1.x = r->x*scale;
00218 pt2.x = (r->x+r->width)*scale;
00219 pt1.y = r->y*scale;
00220 pt2.y = (r->y+r->height)*scale;
00221
00222
00223 cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
00224
00225
00226 tempResults.push_back
00227 (Rectangle::tlbrO(pt1.y,pt1.x,pt2.y,pt2.x));
00228 }
00229 }
00230
00231
00232 cvReleaseImage( &temp );
00233
00234
00235 its_Curr_Res_mutex.lock();
00236 itsCurrentFacesFound.clear();
00237 itsCurrentFacesFound = tempResults;
00238
00239
00240
00241
00242 its_Curr_Res_mutex.unlock();
00243
00244 res = ipl2rgb(img);
00245 return res;
00246 }
00247
00248
00249
00250
00251
00252