1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
8 // Copyright (C) 2009, Farhad Dadgostar
9 // Intel Corporation and third party copyrights are property of their respective owners.
11 // Redistribution and use in source and binary forms, with or without modification,
12 // are permitted provided that the following conditions are met:
14 // * Redistribution's of source code must retain the above copyright notice,
15 // this list of conditions and the following disclaimer.
17 // * Redistribution's in binary form must reproduce the above copyright notice,
18 // this list of conditions and the following disclaimer in the documentation
19 // and/or other materials provided with the distribution.
21 // * The name of Intel Corporation may not be used to endorse or promote products
22 // derived from this software without specific prior written permission.
24 // This software is provided by the copyright holders and contributors "as is" and
25 // any express or implied warranties, including, but not limited to, the implied
26 // warranties of merchantability and fitness for a particular purpose are disclaimed.
27 // In no event shall the Intel Corporation or contributors be liable for any direct,
28 // indirect, incidental, special, exemplary, or consequential damages
29 // (including, but not limited to, procurement of substitute goods or services;
30 // loss of use, data, or profits; or business interruption) however caused
31 // and on any theory of liability, whether in contract, strict liability,
32 // or tort (including negligence or otherwise) arising in any way out of
33 // the use of this software, even if advised of the possibility of such damage.
41 #include "opencv2/contrib/compat.hpp"
42 #include "opencv2/highgui/highgui_c.h"
44 #ifndef _CRT_SECURE_NO_WARNINGS
45 # define _CRT_SECURE_NO_WARNINGS
48 static void help(char **argv)
50 std::cout << "\nThis program demonstrates the contributed flesh detector CvAdaptiveSkinDetector which can be found in contrib.cpp\n"
51 << "Usage: " << std::endl <<
52 argv[0] << " fileMask firstFrame lastFrame" << std::endl << std::endl <<
53 "Example: " << std::endl <<
54 argv[0] << " C:\\VideoSequences\\sample1\\right_view\\temp_%05d.jpg 0 1000" << std::endl <<
55 " iterates through temp_00000.jpg to temp_01000.jpg" << std::endl << std::endl <<
56 "If no parameter specified, this application will try to capture from the default Webcam." << std::endl <<
57 "Please note: Background should not contain large surfaces with skin tone." <<
58 "\n\n ESC will stop\n"
59 "Using OpenCV version %s\n" << CV_VERSION << "\n"
71 virtual ~ASDFrameHolder();
72 virtual void assignFrame(IplImage *sourceImage, double frameTime);
73 inline IplImage *getImage();
74 inline double getTimeStamp();
75 virtual void setImage(IplImage *sourceImage);
78 class ASDFrameSequencer
81 virtual ~ASDFrameSequencer();
82 virtual IplImage *getNextImage();
84 virtual bool isOpen();
85 virtual void getFrameCaption(char *caption);
88 class ASDCVFrameSequencer : public ASDFrameSequencer
94 virtual IplImage *getNextImage();
96 virtual bool isOpen();
99 class ASDFrameSequencerWebCam : public ASDCVFrameSequencer
102 virtual bool open(int cameraIndex);
105 class ASDFrameSequencerVideoFile : public ASDCVFrameSequencer
108 virtual bool open(const char *fileName);
111 class ASDFrameSequencerImageFile : public ASDFrameSequencer {
113 char sFileNameMask[2048];
114 int nCurrentIndex, nStartIndex, nEndIndex;
117 virtual void open(const char *fileNameMask, int startIndex, int endIndex);
118 virtual void getFrameCaption(char *caption);
119 virtual IplImage *getNextImage();
120 virtual void close();
121 virtual bool isOpen();
124 //-------------------- ASDFrameHolder -----------------------//
125 ASDFrameHolder::ASDFrameHolder( )
131 ASDFrameHolder::~ASDFrameHolder( )
133 cvReleaseImage(&image);
136 void ASDFrameHolder::assignFrame(IplImage *sourceImage, double frameTime)
140 cvReleaseImage(&image);
144 image = cvCloneImage(sourceImage);
145 timeStamp = frameTime;
148 IplImage *ASDFrameHolder::getImage()
153 double ASDFrameHolder::getTimeStamp()
158 void ASDFrameHolder::setImage(IplImage *sourceImage)
164 //-------------------- ASDFrameSequencer -----------------------//
166 ASDFrameSequencer::~ASDFrameSequencer()
171 IplImage *ASDFrameSequencer::getNextImage()
176 void ASDFrameSequencer::close()
181 bool ASDFrameSequencer::isOpen()
186 void ASDFrameSequencer::getFrameCaption(char* /*caption*/) {
190 IplImage* ASDCVFrameSequencer::getNextImage()
194 image = cvQueryFrame(capture);
198 return cvCloneImage(image);
206 void ASDCVFrameSequencer::close()
210 cvReleaseCapture(&capture);
214 bool ASDCVFrameSequencer::isOpen()
216 return (capture != NULL);
220 //-------------------- ASDFrameSequencerWebCam -----------------------//
222 bool ASDFrameSequencerWebCam::open(int cameraIndex)
226 capture = cvCaptureFromCAM(cameraIndex);
239 //-------------------- ASDFrameSequencerVideoFile -----------------------//
241 bool ASDFrameSequencerVideoFile::open(const char *fileName)
245 capture = cvCaptureFromFile(fileName);
257 //-------------------- ASDFrameSequencerImageFile -----------------------//
259 void ASDFrameSequencerImageFile::open(const char *fileNameMask, int startIndex, int endIndex)
261 nCurrentIndex = startIndex-1;
262 nStartIndex = startIndex;
263 nEndIndex = endIndex;
265 std::sprintf(sFileNameMask, "%s", fileNameMask);
268 void ASDFrameSequencerImageFile::getFrameCaption(char *caption) {
269 std::sprintf(caption, sFileNameMask, nCurrentIndex);
272 IplImage* ASDFrameSequencerImageFile::getNextImage()
278 if (nCurrentIndex > nEndIndex)
281 std::sprintf(fileName, sFileNameMask, nCurrentIndex);
283 IplImage* img = cvLoadImage(fileName);
288 void ASDFrameSequencerImageFile::close()
290 nCurrentIndex = nEndIndex+1;
293 bool ASDFrameSequencerImageFile::isOpen()
295 return (nCurrentIndex <= nEndIndex);
298 static void putTextWithShadow(IplImage *img, const char *str, CvPoint point, CvFont *font, CvScalar color = CV_RGB(255, 255, 128))
300 cvPutText(img, str, cvPoint(point.x-1,point.y-1), font, CV_RGB(0, 0, 0));
301 cvPutText(img, str, point, font, color);
304 #define ASD_RGB_SET_PIXEL(pointer, r, g, b) { (*pointer) = (unsigned char)b; (*(pointer+1)) = (unsigned char)g; (*(pointer+2)) = (unsigned char)r; }
306 #define ASD_RGB_GET_PIXEL(pointer, r, g, b) {b = (unsigned char)(*(pointer)); g = (unsigned char)(*(pointer+1)); r = (unsigned char)(*(pointer+2));}
308 static void displayBuffer(IplImage *rgbDestImage, IplImage *buffer, int rValue, int gValue, int bValue)
310 int x, y, nWidth, nHeight;
311 double destX, destY, dx, dy;
315 nWidth = buffer->width;
316 nHeight = buffer->height;
318 dx = double(rgbDestImage->width)/double(nWidth);
319 dy = double(rgbDestImage->height)/double(nHeight);
322 for (x = 0; x < nWidth; x++)
325 for (y = 0; y < nHeight; y++)
327 c = ((uchar*)(buffer->imageData + buffer->widthStep*y))[x];
331 pSrc = (unsigned char *)rgbDestImage->imageData + rgbDestImage->widthStep*int(destY) + (int(destX)*rgbDestImage->nChannels);
332 ASD_RGB_SET_PIXEL(pSrc, rValue, gValue, bValue);
341 int main(int argc, char** argv )
343 IplImage *img, *filterMask = NULL;
344 CvAdaptiveSkinDetector filter(1, CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE);
345 ASDFrameSequencer *sequencer;
347 char caption[2048], s[256], windowName[256];
348 long int clockTotal = 0, numFrames = 0;
354 sequencer = new ASDFrameSequencerWebCam();
355 (dynamic_cast<ASDFrameSequencerWebCam*>(sequencer))->open(-1);
357 if (! sequencer->isOpen())
359 std::cout << std::endl << "Error: Cannot initialize the default Webcam" << std::endl << std::endl;
364 sequencer = new ASDFrameSequencerImageFile();
365 (dynamic_cast<ASDFrameSequencerImageFile*>(sequencer))->open(argv[1], std::atoi(argv[2]), std::atoi(argv[3]) ); // A sequence of images captured from video source, is stored here
368 std::sprintf(windowName, "%s", "Adaptive Skin Detection Algorithm for Video Sequences");
370 cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE);
371 cvInitFont( &base_font, CV_FONT_VECTOR0, 0.5, 0.5);
374 // c:\>CvASDSample "C:\VideoSequences\sample1\right_view\temp_%05d.jpg" 0 1000
376 std::cout << "Press ESC to stop." << std::endl << std::endl;
377 while ((img = sequencer->getNextImage()) != 0)
381 if (filterMask == NULL)
383 filterMask = cvCreateImage( cvSize(img->width, img->height), IPL_DEPTH_8U, 1);
385 clock = std::clock();
386 filter.process(img, filterMask); // DETECT SKIN
387 clockTotal += (std::clock() - clock);
389 displayBuffer(img, filterMask, 0, 255, 0);
391 sequencer->getFrameCaption(caption);
392 std::sprintf(s, "%s - %d x %d", caption, img->width, img->height);
393 putTextWithShadow(img, s, cvPoint(10, img->height-35), &base_font);
395 std::sprintf(s, "Average processing time per frame: %5.2fms", (double(clockTotal*1000/CLOCKS_PER_SEC))/numFrames);
396 putTextWithShadow(img, s, cvPoint(10, img->height-15), &base_font);
398 cvShowImage (windowName, img);
399 cvReleaseImage(&img);
401 if (cvWaitKey(1) == 27)
408 cvReleaseImage(&filterMask);
410 cvDestroyWindow(windowName);
412 std::cout << "Finished, " << numFrames << " frames processed." << std::endl;