PageRenderTime 61ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/source/3rd_party/opencv/sources/samples/c/adaptiveskindetector.cpp

https://gitlab.com/Ruggero/SparkEngine_Desktop
C++ | 415 lines | 293 code | 80 blank | 42 comment | 21 complexity | 472b09ef4d40d58ca9fb42cf58f16b6a MD5 | raw file
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  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.
  7. //
  8. // Copyright (C) 2009, Farhad Dadgostar
  9. // Intel Corporation and third party copyrights are property of their respective owners.
  10. //
  11. // Redistribution and use in source and binary forms, with or without modification,
  12. // are permitted provided that the following conditions are met:
  13. //
  14. // * Redistribution's of source code must retain the above copyright notice,
  15. // this list of conditions and the following disclaimer.
  16. //
  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.
  20. //
  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.
  23. //
  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.
  34. //
  35. //M*/
  36. #include <iostream>
  37. #include <cstdio>
  38. #include <cstring>
  39. #include <ctime>
  40. #include "opencv2/contrib/contrib.hpp"
  41. #include "opencv2/highgui/highgui.hpp"
  42. #ifndef _CRT_SECURE_NO_WARNINGS
  43. # define _CRT_SECURE_NO_WARNINGS
  44. #endif
  45. static void help(char **argv)
  46. {
  47. std::cout << "\nThis program demonstrates the contributed flesh detector CvAdaptiveSkinDetector which can be found in contrib.cpp\n"
  48. << "Usage: " << std::endl <<
  49. argv[0] << " fileMask firstFrame lastFrame" << std::endl << std::endl <<
  50. "Example: " << std::endl <<
  51. argv[0] << " C:\\VideoSequences\\sample1\\right_view\\temp_%05d.jpg 0 1000" << std::endl <<
  52. " iterates through temp_00000.jpg to temp_01000.jpg" << std::endl << std::endl <<
  53. "If no parameter specified, this application will try to capture from the default Webcam." << std::endl <<
  54. "Please note: Background should not contain large surfaces with skin tone." <<
  55. "\n\n ESC will stop\n"
  56. "Using OpenCV version %s\n" << CV_VERSION << "\n"
  57. << std::endl;
  58. }
  59. class ASDFrameHolder
  60. {
  61. private:
  62. IplImage *image;
  63. double timeStamp;
  64. public:
  65. ASDFrameHolder();
  66. virtual ~ASDFrameHolder();
  67. virtual void assignFrame(IplImage *sourceImage, double frameTime);
  68. inline IplImage *getImage();
  69. inline double getTimeStamp();
  70. virtual void setImage(IplImage *sourceImage);
  71. };
  72. class ASDFrameSequencer
  73. {
  74. public:
  75. virtual ~ASDFrameSequencer();
  76. virtual IplImage *getNextImage();
  77. virtual void close();
  78. virtual bool isOpen();
  79. virtual void getFrameCaption(char *caption);
  80. };
  81. class ASDCVFrameSequencer : public ASDFrameSequencer
  82. {
  83. protected:
  84. CvCapture *capture;
  85. public:
  86. virtual IplImage *getNextImage();
  87. virtual void close();
  88. virtual bool isOpen();
  89. };
  90. class ASDFrameSequencerWebCam : public ASDCVFrameSequencer
  91. {
  92. public:
  93. virtual bool open(int cameraIndex);
  94. };
  95. class ASDFrameSequencerVideoFile : public ASDCVFrameSequencer
  96. {
  97. public:
  98. virtual bool open(const char *fileName);
  99. };
  100. class ASDFrameSequencerImageFile : public ASDFrameSequencer {
  101. private:
  102. char sFileNameMask[2048];
  103. int nCurrentIndex, nStartIndex, nEndIndex;
  104. public:
  105. virtual void open(const char *fileNameMask, int startIndex, int endIndex);
  106. virtual void getFrameCaption(char *caption);
  107. virtual IplImage *getNextImage();
  108. virtual void close();
  109. virtual bool isOpen();
  110. };
  111. //-------------------- ASDFrameHolder -----------------------//
  112. ASDFrameHolder::ASDFrameHolder( )
  113. {
  114. image = NULL;
  115. timeStamp = 0;
  116. }
  117. ASDFrameHolder::~ASDFrameHolder( )
  118. {
  119. cvReleaseImage(&image);
  120. }
  121. void ASDFrameHolder::assignFrame(IplImage *sourceImage, double frameTime)
  122. {
  123. if (image != NULL)
  124. {
  125. cvReleaseImage(&image);
  126. image = NULL;
  127. }
  128. image = cvCloneImage(sourceImage);
  129. timeStamp = frameTime;
  130. }
  131. IplImage *ASDFrameHolder::getImage()
  132. {
  133. return image;
  134. }
  135. double ASDFrameHolder::getTimeStamp()
  136. {
  137. return timeStamp;
  138. }
  139. void ASDFrameHolder::setImage(IplImage *sourceImage)
  140. {
  141. image = sourceImage;
  142. }
  143. //-------------------- ASDFrameSequencer -----------------------//
  144. ASDFrameSequencer::~ASDFrameSequencer()
  145. {
  146. close();
  147. }
  148. IplImage *ASDFrameSequencer::getNextImage()
  149. {
  150. return NULL;
  151. }
  152. void ASDFrameSequencer::close()
  153. {
  154. }
  155. bool ASDFrameSequencer::isOpen()
  156. {
  157. return false;
  158. }
  159. void ASDFrameSequencer::getFrameCaption(char* /*caption*/) {
  160. return;
  161. }
  162. IplImage* ASDCVFrameSequencer::getNextImage()
  163. {
  164. IplImage *image;
  165. image = cvQueryFrame(capture);
  166. if (image != NULL)
  167. {
  168. return cvCloneImage(image);
  169. }
  170. else
  171. {
  172. return NULL;
  173. }
  174. }
  175. void ASDCVFrameSequencer::close()
  176. {
  177. if (capture != NULL)
  178. {
  179. cvReleaseCapture(&capture);
  180. }
  181. }
  182. bool ASDCVFrameSequencer::isOpen()
  183. {
  184. return (capture != NULL);
  185. }
  186. //-------------------- ASDFrameSequencerWebCam -----------------------//
  187. bool ASDFrameSequencerWebCam::open(int cameraIndex)
  188. {
  189. close();
  190. capture = cvCaptureFromCAM(cameraIndex);
  191. if (!capture)
  192. {
  193. return false;
  194. }
  195. else
  196. {
  197. return true;
  198. }
  199. }
  200. //-------------------- ASDFrameSequencerVideoFile -----------------------//
  201. bool ASDFrameSequencerVideoFile::open(const char *fileName)
  202. {
  203. close();
  204. capture = cvCaptureFromFile(fileName);
  205. if (!capture)
  206. {
  207. return false;
  208. }
  209. else
  210. {
  211. return true;
  212. }
  213. }
  214. //-------------------- ASDFrameSequencerImageFile -----------------------//
  215. void ASDFrameSequencerImageFile::open(const char *fileNameMask, int startIndex, int endIndex)
  216. {
  217. nCurrentIndex = startIndex-1;
  218. nStartIndex = startIndex;
  219. nEndIndex = endIndex;
  220. std::sprintf(sFileNameMask, "%s", fileNameMask);
  221. }
  222. void ASDFrameSequencerImageFile::getFrameCaption(char *caption) {
  223. std::sprintf(caption, sFileNameMask, nCurrentIndex);
  224. }
  225. IplImage* ASDFrameSequencerImageFile::getNextImage()
  226. {
  227. char fileName[2048];
  228. nCurrentIndex++;
  229. if (nCurrentIndex > nEndIndex)
  230. return NULL;
  231. std::sprintf(fileName, sFileNameMask, nCurrentIndex);
  232. IplImage* img = cvLoadImage(fileName);
  233. return img;
  234. }
  235. void ASDFrameSequencerImageFile::close()
  236. {
  237. nCurrentIndex = nEndIndex+1;
  238. }
  239. bool ASDFrameSequencerImageFile::isOpen()
  240. {
  241. return (nCurrentIndex <= nEndIndex);
  242. }
  243. static void putTextWithShadow(IplImage *img, const char *str, CvPoint point, CvFont *font, CvScalar color = CV_RGB(255, 255, 128))
  244. {
  245. cvPutText(img, str, cvPoint(point.x-1,point.y-1), font, CV_RGB(0, 0, 0));
  246. cvPutText(img, str, point, font, color);
  247. }
  248. #define ASD_RGB_SET_PIXEL(pointer, r, g, b) { (*pointer) = (unsigned char)b; (*(pointer+1)) = (unsigned char)g; (*(pointer+2)) = (unsigned char)r; }
  249. #define ASD_RGB_GET_PIXEL(pointer, r, g, b) {b = (unsigned char)(*(pointer)); g = (unsigned char)(*(pointer+1)); r = (unsigned char)(*(pointer+2));}
  250. static void displayBuffer(IplImage *rgbDestImage, IplImage *buffer, int rValue, int gValue, int bValue)
  251. {
  252. int x, y, nWidth, nHeight;
  253. double destX, destY, dx, dy;
  254. uchar c;
  255. unsigned char *pSrc;
  256. nWidth = buffer->width;
  257. nHeight = buffer->height;
  258. dx = double(rgbDestImage->width)/double(nWidth);
  259. dy = double(rgbDestImage->height)/double(nHeight);
  260. destX = 0;
  261. for (x = 0; x < nWidth; x++)
  262. {
  263. destY = 0;
  264. for (y = 0; y < nHeight; y++)
  265. {
  266. c = ((uchar*)(buffer->imageData + buffer->widthStep*y))[x];
  267. if (c)
  268. {
  269. pSrc = (unsigned char *)rgbDestImage->imageData + rgbDestImage->widthStep*int(destY) + (int(destX)*rgbDestImage->nChannels);
  270. ASD_RGB_SET_PIXEL(pSrc, rValue, gValue, bValue);
  271. }
  272. destY += dy;
  273. }
  274. destY = 0;
  275. destX += dx;
  276. }
  277. }
  278. int main(int argc, char** argv )
  279. {
  280. IplImage *img, *filterMask = NULL;
  281. CvAdaptiveSkinDetector filter(1, CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE);
  282. ASDFrameSequencer *sequencer;
  283. CvFont base_font;
  284. char caption[2048], s[256], windowName[256];
  285. long int clockTotal = 0, numFrames = 0;
  286. std::clock_t clock;
  287. if (argc < 4)
  288. {
  289. help(argv);
  290. sequencer = new ASDFrameSequencerWebCam();
  291. (dynamic_cast<ASDFrameSequencerWebCam*>(sequencer))->open(-1);
  292. if (! sequencer->isOpen())
  293. {
  294. std::cout << std::endl << "Error: Cannot initialize the default Webcam" << std::endl << std::endl;
  295. }
  296. }
  297. else
  298. {
  299. sequencer = new ASDFrameSequencerImageFile();
  300. (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
  301. }
  302. std::sprintf(windowName, "%s", "Adaptive Skin Detection Algorithm for Video Sequences");
  303. cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE);
  304. cvInitFont( &base_font, CV_FONT_VECTOR0, 0.5, 0.5);
  305. // Usage:
  306. // c:\>CvASDSample "C:\VideoSequences\sample1\right_view\temp_%05d.jpg" 0 1000
  307. std::cout << "Press ESC to stop." << std::endl << std::endl;
  308. while ((img = sequencer->getNextImage()) != 0)
  309. {
  310. numFrames++;
  311. if (filterMask == NULL)
  312. {
  313. filterMask = cvCreateImage( cvSize(img->width, img->height), IPL_DEPTH_8U, 1);
  314. }
  315. clock = std::clock();
  316. filter.process(img, filterMask); // DETECT SKIN
  317. clockTotal += (std::clock() - clock);
  318. displayBuffer(img, filterMask, 0, 255, 0);
  319. sequencer->getFrameCaption(caption);
  320. std::sprintf(s, "%s - %d x %d", caption, img->width, img->height);
  321. putTextWithShadow(img, s, cvPoint(10, img->height-35), &base_font);
  322. std::sprintf(s, "Average processing time per frame: %5.2fms", (double(clockTotal*1000/CLOCKS_PER_SEC))/numFrames);
  323. putTextWithShadow(img, s, cvPoint(10, img->height-15), &base_font);
  324. cvShowImage (windowName, img);
  325. cvReleaseImage(&img);
  326. if (cvWaitKey(1) == 27)
  327. break;
  328. }
  329. sequencer->close();
  330. delete sequencer;
  331. cvReleaseImage(&filterMask);
  332. cvDestroyWindow(windowName);
  333. std::cout << "Finished, " << numFrames << " frames processed." << std::endl;
  334. return 0;
  335. }