PageRenderTime 128ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/opencv/src/adaptiveskindetector.cpp

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