1 /*M///////////////////////////////////////////////////////////////////////////////////////
\r
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
\r
5 // By downloading, copying, installing or using the software you agree to this license.
\r
6 // If you do not agree to this license, do not download, install, copy or use the software.
\r
8 // Copyright (C) 2009, Farhad Dadgostar
\r
9 // Intel Corporation and third party copyrights are property of their respective owners.
\r
11 // Redistribution and use in source and binary forms, with or without modification,
\r
12 // are permitted provided that the following conditions are met:
\r
14 // * Redistribution's of source code must retain the above copyright notice,
\r
15 // this list of conditions and the following disclaimer.
\r
17 // * Redistribution's in binary form must reproduce the above copyright notice,
\r
18 // this list of conditions and the following disclaimer in the documentation
\r
19 // and/or other materials provided with the distribution.
\r
21 // * The name of Intel Corporation may not be used to endorse or promote products
\r
22 // derived from this software without specific prior written permission.
\r
24 // This software is provided by the copyright holders and contributors "as is" and
\r
25 // any express or implied warranties, including, but not limited to, the implied
\r
26 // warranties of merchantability and fitness for a particular purpose are disclaimed.
\r
27 // In no event shall the Intel Corporation or contributors be liable for any direct,
\r
28 // indirect, incidental, special, exemplary, or consequential damages
\r
29 // (including, but not limited to, procurement of substitute goods or services;
\r
30 // loss of use, data, or profits; or business interruption) however caused
\r
31 // and on any theory of liability, whether in contract, strict liability,
\r
32 // or tort (including negligence or otherwise) arising in any way out of
\r
33 // the use of this software, even if advised of the possibility of such damage.
\r
38 #include <opencv2/core/core.hpp>
\r
39 #include <opencv2/contrib/contrib.hpp>
\r
40 #include <opencv2/highgui/highgui.hpp>
\r
47 using namespace std;
\r
50 class ASDFrameHolder
\r
58 virtual ~ASDFrameHolder();
\r
59 virtual void assignFrame(IplImage *sourceImage, double frameTime);
\r
60 inline IplImage *getImage();
\r
61 inline double getTimeStamp();
\r
62 virtual void setImage(IplImage *sourceImage);
\r
65 class ASDFrameSequencer
\r
68 virtual ~ASDFrameSequencer();
\r
69 virtual IplImage *getNextImage();
\r
70 virtual void close();
\r
71 virtual bool isOpen();
\r
72 virtual void getFrameCaption(char *caption);
\r
75 class ASDCVFrameSequencer : public ASDFrameSequencer
\r
81 virtual IplImage *getNextImage();
\r
82 virtual void close();
\r
83 virtual bool isOpen();
\r
86 class ASDFrameSequencerWebCam : public ASDCVFrameSequencer
\r
89 virtual bool open(int cameraIndex);
\r
92 class ASDFrameSequencerVideoFile : public ASDCVFrameSequencer
\r
95 virtual bool open(const char *fileName);
\r
98 class ASDFrameSequencerImageFile : public ASDFrameSequencer {
\r
100 char sFileNameMask[2048];
\r
101 int nCurrentIndex, nStartIndex, nEndIndex;
\r
104 virtual void open(const char *fileNameMask, int startIndex, int endIndex);
\r
105 virtual void getFrameCaption(char *caption);
\r
106 virtual IplImage *getNextImage();
\r
107 virtual void close();
\r
108 virtual bool isOpen();
\r
111 //-------------------- ASDFrameHolder -----------------------//
\r
112 ASDFrameHolder::ASDFrameHolder( )
\r
118 ASDFrameHolder::~ASDFrameHolder( )
\r
120 cvReleaseImage(&image);
\r
123 void ASDFrameHolder::assignFrame(IplImage *sourceImage, double frameTime)
\r
127 cvReleaseImage(&image);
\r
131 image = cvCloneImage(sourceImage);
\r
132 timeStamp = frameTime;
\r
135 IplImage *ASDFrameHolder::getImage()
\r
140 double ASDFrameHolder::getTimeStamp()
\r
145 void ASDFrameHolder::setImage(IplImage *sourceImage)
\r
147 image = sourceImage;
\r
151 //-------------------- ASDFrameSequencer -----------------------//
\r
152 ASDFrameSequencer::~ASDFrameSequencer()
\r
157 IplImage *ASDFrameSequencer::getNextImage()
\r
162 void ASDFrameSequencer::close()
\r
167 bool ASDFrameSequencer::isOpen()
\r
172 void ASDFrameSequencer::getFrameCaption(char* /*caption*/) {
\r
176 IplImage* ASDCVFrameSequencer::getNextImage()
\r
180 image = cvQueryFrame(capture);
\r
184 return cvCloneImage(image);
\r
192 void ASDCVFrameSequencer::close()
\r
194 if (capture != NULL)
\r
196 cvReleaseCapture(&capture);
\r
200 bool ASDCVFrameSequencer::isOpen()
\r
202 return (capture != NULL);
\r
206 //-------------------- ASDFrameSequencerWebCam -----------------------//
\r
207 bool ASDFrameSequencerWebCam::open(int cameraIndex)
\r
211 capture = cvCaptureFromCAM(cameraIndex);
\r
224 //-------------------- ASDFrameSequencerVideoFile -----------------------//
\r
226 bool ASDFrameSequencerVideoFile::open(const char *fileName)
\r
230 capture = cvCaptureFromFile(fileName);
\r
242 //-------------------- ASDFrameSequencerImageFile -----------------------//
\r
244 void ASDFrameSequencerImageFile::open(const char *fileNameMask, int startIndex, int endIndex)
\r
246 nCurrentIndex = startIndex-1;
\r
247 nStartIndex = startIndex;
\r
248 nEndIndex = endIndex;
\r
250 std::sprintf(sFileNameMask, "%s", fileNameMask);
\r
253 void ASDFrameSequencerImageFile::getFrameCaption(char *caption) {
\r
254 std::sprintf(caption, sFileNameMask, nCurrentIndex);
\r
257 IplImage* ASDFrameSequencerImageFile::getNextImage()
\r
259 char fileName[2048];
\r
263 if (nCurrentIndex > nEndIndex)
\r
266 std::sprintf(fileName, sFileNameMask, nCurrentIndex);
\r
268 IplImage* img = cvLoadImage(fileName);
\r
273 void ASDFrameSequencerImageFile::close()
\r
275 nCurrentIndex = nEndIndex+1;
\r
278 bool ASDFrameSequencerImageFile::isOpen()
\r
280 return (nCurrentIndex <= nEndIndex);
\r
283 void putTextWithShadow(IplImage *img, const char *str, CvPoint point, CvFont *font, CvScalar color = CV_RGB(255, 255, 128))
\r
285 cvPutText(img, str, cvPoint(point.x-1,point.y-1), font, CV_RGB(0, 0, 0));
\r
286 cvPutText(img, str, point, font, color);
\r
289 #define ASD_RGB_SET_PIXEL(pointer, r, g, b) { (*pointer) = (unsigned char)b; (*(pointer+1)) = (unsigned char)g; (*(pointer+2)) = (unsigned char)r; }
\r
291 #define ASD_RGB_GET_PIXEL(pointer, r, g, b) {b = (unsigned char)(*(pointer)); g = (unsigned char)(*(pointer+1)); r = (unsigned char)(*(pointer+2));}
\r
293 void displayBuffer(IplImage *rgbDestImage, IplImage *buffer, int rValue, int gValue, int bValue)
\r
295 int x, y, nWidth, nHeight;
\r
296 double destX, destY, dx, dy;
\r
298 unsigned char *pSrc;
\r
300 nWidth = buffer->width;
\r
301 nHeight = buffer->height;
\r
303 dx = double(rgbDestImage->width)/double(nWidth);
\r
304 dy = double(rgbDestImage->height)/double(nHeight);
\r
307 for (x = 0; x < nWidth; x++)
\r
310 for (y = 0; y < nHeight; y++)
\r
312 c = ((uchar*)(buffer->imageData + buffer->widthStep*y))[x];
\r
316 pSrc = (unsigned char *)rgbDestImage->imageData + rgbDestImage->widthStep*int(destY) + (int(destX)*rgbDestImage->nChannels);
\r
317 ASD_RGB_SET_PIXEL(pSrc, rValue, gValue, bValue);
\r
326 void help(const char *exe_name)
\r
328 std::cout << "\nThis program demonstrates the contributed flesh detector CvAdaptiveSkinDetector which can be found in contrib.cpp\n"
\r
329 << "Usage: " << std::endl <<
\r
330 exe_name << " --fileMask --firstFrame --lastFrame" << std::endl << std::endl <<
\r
331 "Example: " << std::endl <<
\r
332 exe_name << " --fileMask=C:\\VideoSequences\\sample1\\right_view\\temp_%05d.jpg --firstFrame=0 --lastFrame=1000" << std::endl <<
\r
333 " iterates through temp_00000.jpg to temp_01000.jpg" << std::endl << std::endl <<
\r
334 "If no parameter specified, this application will try to capture from the default Webcam." << std::endl <<
\r
335 "Please note: Background should not contain large surfaces with skin tone." <<
\r
336 "\n\n ESC will stop\n"
\r
337 "Using OpenCV version %s\n" << CV_VERSION << "\n"
\r
341 int main(int argc, const char** argv )
\r
345 CommandLineParser parser(argc, argv);
\r
347 string fileMask = parser.get<string>("fileMask");
\r
348 int firstFrame = parser.get<int>("firstFrame", 0);
\r
349 int lastFrame = parser.get<int>("lastFrame", 0);
\r
351 IplImage *img, *filterMask = NULL;
\r
352 CvAdaptiveSkinDetector filter(1, CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE);
\r
353 ASDFrameSequencer *sequencer;
\r
355 char caption[2048], s[256], windowName[256];
\r
356 long int clockTotal = 0, numFrames = 0;
\r
357 std::clock_t clock;
\r
361 sequencer = new ASDFrameSequencerWebCam();
\r
362 (dynamic_cast<ASDFrameSequencerWebCam*>(sequencer))->open(-1);
\r
364 if (! sequencer->isOpen())
\r
366 std::cout << std::endl << "Error: Cannot initialize the default Webcam" << std::endl << std::endl;
\r
371 // A sequence of images captured from video source, is stored here
\r
372 sequencer = new ASDFrameSequencerImageFile();
\r
373 (dynamic_cast<ASDFrameSequencerImageFile*>(sequencer))->open(fileMask.c_str(), firstFrame, lastFrame );
\r
376 std::sprintf(windowName, "%s", "Adaptive Skin Detection Algorithm for Video Sequences");
\r
378 cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE);
\r
379 cvInitFont( &base_font, CV_FONT_VECTOR0, 0.5, 0.5);
\r
381 while ((img = sequencer->getNextImage()) != 0)
\r
385 if (filterMask == NULL)
\r
387 filterMask = cvCreateImage( cvSize(img->width, img->height), IPL_DEPTH_8U, 1);
\r
389 clock = std::clock();
\r
390 filter.process(img, filterMask); // DETECT SKIN
\r
391 clockTotal += (std::clock() - clock);
\r
393 displayBuffer(img, filterMask, 0, 255, 0);
\r
395 sequencer->getFrameCaption(caption);
\r
396 std::sprintf(s, "%s - %d x %d", caption, img->width, img->height);
\r
397 putTextWithShadow(img, s, cvPoint(10, img->height-35), &base_font);
\r
399 std::sprintf(s, "Average processing time per frame: %5.2fms", (double(clockTotal*1000/CLOCKS_PER_SEC))/numFrames);
\r
400 putTextWithShadow(img, s, cvPoint(10, img->height-15), &base_font);
\r
402 cvShowImage (windowName, img);
\r
403 cvReleaseImage(&img);
\r
405 if (cvWaitKey(1) == 27)
\r
409 sequencer->close();
\r
412 cvReleaseImage(&filterMask);
\r
414 cvDestroyWindow(windowName);
\r
416 std::cout << "Finished, " << numFrames << " frames processed." << std::endl;
\r