alexcpn

Untitled

Mar 1st, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.08 KB | None | 0 0
  1. //#include <stdafx.h>
  2. #include <iostream>
  3. #include <time.h>
  4.  
  5. #include "opencv2/objdetect.hpp"
  6. #include "opencv2/highgui.hpp"
  7. #include "opencv2/imgproc.hpp"
  8.  
  9. #include "opencv2/cudaobjdetect.hpp"
  10. #include "opencv2/cudaimgproc.hpp"
  11. #include "opencv2/cudawarping.hpp"
  12. #include "opencv2/core/cuda.hpp"
  13.  
  14. #include <boost/property_tree/ptree.hpp>
  15. #include <boost/property_tree/ini_parser.hpp>
  16. #include <boost/lexical_cast.hpp>
  17.  
  18. using namespace std;
  19. using namespace cv;
  20. using namespace cv::cuda;
  21. using namespace boost;
  22.  
  23.  
  24. /** Global variables */
  25. String opencv_path = "~/opencv";
  26. String videoFile = "";
  27. String outFile = "/tmp/out.avi";
  28. String useAlgo = "hog";
  29. bool useGpu = false;
  30. int counter_frames_processed = 0;
  31. int counter_frames_skipped = 0;
  32. int counter_frames_detected = 0;
  33. Size downFrameSize(640, 480);
  34.  
  35. Ptr<cuda::CascadeClassifier> cascade_gpu_upperbody, cascade_gpu_lowerbody, cascade_gpu_fullbody;
  36. Ptr<cv::cuda::HOG> gpu_hog;
  37. std::string getPropertyVal(string file_name,string key);
  38. /*
  39. These are the setting for HOG Person detector; There is no one setting that is good for all
  40. Using daimlerpeopledetector ,see where the SVM is set
  41. Default people detector getDefaultPeopleDetector work only with win_width = 48, with GPU it works with
  42. win_width = 64 as well; but detection rate is very poor
  43. -->OpenCV Error : Assertion failed(checkDetectorSize()) in cv::HOGDescriptor::setSVMDetector
  44. */
  45. int win_width = 48;
  46. //48*96 rectangle is found for HOG
  47. int cell_width = 8;
  48. int nbins = 9;
  49. int win_stride_width = 8;
  50. int block_width = win_stride_width*2;
  51.  
  52. int hogLevels = HOGDescriptor::DEFAULT_NLEVELS;
  53. int hogGroupThreshold = lexical_cast<int>(getPropertyVal("config.ini","HOG.hogGroupThreshold"));//
  54. Size cell_size(cell_width, cell_width);
  55.  
  56. /* From above these below are standard setting*/
  57. Size win_stride(win_stride_width, win_stride_width);
  58. Size win_size(win_width, win_width * 2);
  59. Size block_size(block_width, block_width);
  60. int block_stride_width = block_width / 2;
  61. int block_stride_height = block_width / 2;
  62. Size block_stride(block_stride_width, block_stride_height);
  63.  
  64.  
  65. cv::HOGDescriptor cpu_hog(win_size, block_size, block_stride, cell_size, nbins, 1, -1,
  66. HOGDescriptor::L2Hys, .2, false, hogLevels);
  67.  
  68. cv::CascadeClassifier upperbody_cascade;
  69. cv::CascadeClassifier lowerbody_cascade;
  70. cv::CascadeClassifier fullbody_cascade;
  71.  
  72. /**
  73. Sclar - BGR value
  74. **/
  75. void drawMarker(Mat img, std::vector<cv::Rect> found, Scalar sc, int size = 2) {
  76.  
  77. for (int i = 0; i < (int)found.size(); i++)
  78. {
  79. cv::Rect r = found[i];
  80. cv::rectangle(img, r, sc, size);
  81. }
  82. }
  83.  
  84. std::string getPropertyVal(string file_name,string key){
  85.  
  86. boost::property_tree::ptree pt;
  87. boost::property_tree::ini_parser::read_ini(file_name, pt);
  88. std::string temp = pt.get<std::string>(key);
  89. return temp;
  90. }
  91.  
  92. /** @function detectAndDisplay using CPU */
  93. void detectAndDisplayHOG(Mat img, VideoWriter oVideoWriter, bool useGPU)
  94. {
  95. Mat frame;
  96. std::vector<cv::Rect> found;
  97. //The GroupThreshold and ScaleFactor are the two important parameters
  98. //decrease will get more hits, with more false positives
  99. int _hitThreshold = 0;// //going mad tuning this for cuda// not to be adjusted
  100. //decrease will get more hits, with more false positives
  101. double _scaleFactor = lexical_cast<double>(getPropertyVal("config.ini","HOG.scaleFactor"));//1.05;// 20 sec --> huge impact on performance
  102. int cell_height = lexical_cast<int>(getPropertyVal("config.ini","HOG.min_cell_size"));
  103.  
  104. if (useGPU) {
  105. cv::cvtColor(img, frame, COLOR_BGR2BGRA);// COLOR_BGR2BGRA);
  106. GpuMat gpuFrame(frame);
  107. gpu_hog->setScaleFactor(_scaleFactor);
  108. gpu_hog->setNumLevels(hogLevels);
  109. gpu_hog->setWinStride(win_stride);
  110. //gpu_hog->setHitThreshold(0); // play with this at your own risk :)
  111. gpu_hog->setGroupThreshold(hogGroupThreshold);// setting it to higher will reduce false positives// give all
  112. gpu_hog->detectMultiScale(gpuFrame, found);
  113. drawMarker(img, found, Scalar(255, 0, 0), 1);//BGR
  114. //gpu_hog->setGroupThreshold(hogGroupThreshold*3);// setting it to higher will group more
  115. //gpu_hog->detectMultiScale(gpuFrame, found);
  116. //drawMarker(img, found, Scalar(0, 255, 0));//BGR
  117. }
  118. else
  119. {
  120. cv::cvtColor(img, frame, COLOR_BGR2GRAY);//(img.type() == CV_8U || img.type() == CV_8UC3)
  121. cpu_hog.detectMultiScale(frame, found, _hitThreshold, win_stride, cv::Size(cell_height, cell_height), _scaleFactor);
  122. drawMarker(img, found, Scalar(255, 0, 0));//BGR
  123.  
  124. }
  125. if (found.size() > 1) {
  126. counter_frames_detected += 1;
  127. }
  128.  
  129. oVideoWriter.write(img);
  130. imshow("opencv", img);
  131. }
  132.  
  133. /** Helper funcitons**/
  134. void setCudaClassifierProperties(Ptr<cuda::CascadeClassifier> classifier) {
  135.  
  136. classifier->setScaleFactor(1.02); // The smaller it is the better, though tradeoff is processing (should be >1 )
  137. classifier->setMinNeighbors(3); // the larger this is there would be less false positives;
  138. // However it will also start to miss ;best is 3 to 4, but there are misses wiht this
  139.  
  140. }
  141. /** Helper funcitons**/
  142. void run_classifier_detection(Ptr<cuda::CascadeClassifier> classifier, GpuMat gpuGreyFrame, std::vector<cv::Rect> *found) {
  143. GpuMat facesBuf_gpu;
  144. //Now let the cascaders run
  145. setCudaClassifierProperties(classifier);
  146. classifier->detectMultiScale(gpuGreyFrame, facesBuf_gpu);
  147. classifier->convert(facesBuf_gpu, *found);
  148. }
  149.  
  150.  
  151.  
  152. /** @function detectAndDisplay using CPU */
  153. void detectAndDisplayHAAR(Mat img, VideoWriter oVideoWriter, bool useGPU)
  154. {
  155.  
  156. Mat frame;
  157. cv::cvtColor(img, frame, COLOR_BGR2GRAY);
  158. std::vector<cv::Rect> found;
  159. //-- Detect Upper body classifier
  160. // http://fewtutorials.bravesites.com/entries/emgu-cv-c/level-3c---how-to-improve-face-detection
  161.  
  162. //Now let the cascaders run, we are running three cascades here
  163. // Running on GPU for HAAR is much faster than for CPU
  164.  
  165. //Now let the cascaders run, we are running three cascades here
  166. // Running on GPU for HAAR is much faster than for CPU
  167. if (useGPU) {
  168.  
  169. GpuMat gray_gpu(frame);// , gray_gpu, resized_gpu;
  170. //Need to convert and resize before it is able to detect
  171. run_classifier_detection(cascade_gpu_upperbody, gray_gpu, &found);
  172. drawMarker(img, found, Scalar(0, 255, 0));//Green .BGR
  173.  
  174. run_classifier_detection(cascade_gpu_fullbody, gray_gpu, &found);
  175. drawMarker(img, found, Scalar(0, 0, 255));//BGR
  176.  
  177. run_classifier_detection(cascade_gpu_lowerbody, gray_gpu, &found);
  178. drawMarker(img, found, Scalar(255, 0, 0));//BGR
  179.  
  180. }else {
  181.  
  182.  
  183. double scalingFactor = 1.05;// with 1.001,too much false positive
  184. int numberOfNeighbours = 3;
  185.  
  186. upperbody_cascade.detectMultiScale(frame, found, scalingFactor, numberOfNeighbours, 0, cv::Size(30, 30));
  187. drawMarker(img, found, Scalar(0, 255, 0));//Green .BGR
  188.  
  189. lowerbody_cascade.detectMultiScale(frame, found, scalingFactor, numberOfNeighbours, 0, cv::Size(8, 8), cv::Size(32, 32));
  190. drawMarker(img, found, Scalar(0, 0, 255));//BGR
  191.  
  192. fullbody_cascade.detectMultiScale(frame, found, scalingFactor, numberOfNeighbours, 0, cv::Size(8, 8), cv::Size(32, 32));
  193. drawMarker(img, found, Scalar(255, 0, 0));//BGR
  194. }
  195.  
  196. if (found.size() > 1) {
  197. counter_frames_detected += 1;
  198. }
  199. oVideoWriter.write(img);
  200. imshow("opencv", img);
  201.  
  202. }
  203.  
  204.  
  205.  
  206.  
  207.  
  208. // To run this you need OpenCV compiled with CUDA support (and a machine with CUDA compliant /NVDIA GPU card
  209. // Based on the sample program from OpenCV - \opencv\samples\gpu\cascadeclassifier.cpp and other samples in net
  210.  
  211. int main(int argc, char* argv[])
  212. {
  213. cout << "A Simple Object detection test from Video" <<endl;
  214. cout << "Set VIDEO_PATH, OPENCV_PATH, USE_GPU=<0/1> USE_ALGO=haar/hog OUT_PATH <output file *avi full path> in Config.ini " << endl;
  215. ///assert((win_stride_.width % block_stride_.width == 0 && win_stride_.height % block_stride_.height == 0));
  216. //getEnvSetting(videoFile, opencv_path, outFile, useAlgo, useGpu);
  217.  
  218. videoFile = getPropertyVal("config.ini","GENERAL.VIDEO_PATH") ;
  219. opencv_path = getPropertyVal("config.ini","GENERAL.OPENCV_PATH") ;
  220. outFile = getPropertyVal("config.ini","GENERAL.OUT_PATH") ;
  221. useAlgo = getPropertyVal("config.ini","GENERAL.USE_ALGO") ;
  222. useGpu = lexical_cast<bool>(getPropertyVal("config.ini","GENERAL.USE_GPU")) ;
  223.  
  224. cout << "videoFile = " << videoFile << endl;
  225. cout << "opencvpath = " << opencv_path << endl;
  226. cout << "Algorithm Used = " << useAlgo << endl;
  227. cout << "run_on_gpu = " << useGpu << endl;
  228. cout << "outFile = " << outFile << endl;
  229.  
  230. /**
  231. Intialize the Algorithm Settings; The speed as well as false positives depended on these
  232. Unfortunately there is no one setting that is good for all
  233. **/
  234. string device_id =getPropertyVal("config.ini","VIDEO.VIDEO_DEVICE_ID");
  235. VideoCapture cap(lexical_cast<int>(device_id)); // open the video file for reading
  236.  
  237. string frame_width =getPropertyVal("config.ini","VIDEO.CV_CAP_PROP_FRAME_WIDTH");
  238. string frame_height =getPropertyVal("config.ini","VIDEO.CV_CAP_PROP_FRAME_HEIGHT");
  239.  
  240. cap.set(CV_CAP_PROP_FRAME_WIDTH,lexical_cast<int>(frame_width));//640
  241. cap.set(CV_CAP_PROP_FRAME_HEIGHT,lexical_cast<int>(frame_height));//480 for normal cams
  242. if (!cap.isOpened()) // if not success, exit program
  243. {
  244. cout << " Cannot open the video file" << videoFile << endl;
  245. return -1;
  246. }
  247. cout << " Opened the video file" << videoFile << endl;
  248.  
  249. double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
  250. double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
  251. double totalfps = cap.get(CV_CAP_PROP_FRAME_COUNT);
  252. Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
  253. if(! lexical_cast<bool>(getPropertyVal("config.ini","GENERAL.REDUCE_FRAME")) ){
  254. downFrameSize = frameSize; // If you dont want to re-size the frame you could uncomment this , it will take more CPU/GPU
  255. }
  256. cout << " Orginal Frame Size = " << dWidth << "x" << dHeight << endl;
  257. cout << " Reduced Frame Size = " << downFrameSize << endl;
  258.  
  259. double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
  260. cout << "Frame per seconds : " << fps << endl;
  261.  
  262. VideoWriter oVideoWriter(outFile, CV_FOURCC('D', 'I', 'V', 'X'), 3, downFrameSize, true);
  263. if (!oVideoWriter.isOpened()) //if not initialize the VideoWriter successfully, exit the program
  264. {
  265. cout << "ERROR: Failed to write the video" << endl;
  266. return -1;
  267. }
  268.  
  269. if (useGpu) {
  270.  
  271. if (cv::cuda::getCudaEnabledDeviceCount() == 0) {
  272.  
  273. cout << "No GPU found or the library is compiled without CUDA support" << endl;
  274. return -1;
  275. }
  276. cv::cuda::printShortCudaDeviceInfo(cv::cuda::getDevice());
  277.  
  278. if (useAlgo == "hog") {
  279. // If you need to detect other objects you need to train it
  280. // https://github.com/DaHoC/trainHOG
  281. gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, nbins);
  282. Mat detector = gpu_hog->getDefaultPeopleDetector(); //this will select 48*96 or 64*128 based on window size
  283. gpu_hog->setSVMDetector(detector);
  284. cout << "Created the CUDA HOG Classifuer" << endl;
  285. //cout << gpu_hog->getScaleFactor() << "---" << gpu_hog->getGroupThreshold() << endl;
  286. }
  287. else //use harr
  288. {
  289. //The below are the path to the HAAR trained casrcades
  290. //The below taken from http://alereimondo.no-ip.org/OpenCV/34.version?id=60 ; not for commercial use
  291. String upperbody_cascade_name = opencv_path + "/data/HS22x20/HS.xml"; //head and sholders
  292. //The below are CUDA Classisfier does not work with older format Cascade xmls; the below are from OpenCV source
  293. String cuda_lowerbody_cascade_name = opencv_path + "/data/haarcascades_cuda/haarcascade_lowerbody.xml";
  294. String cuda_fullbody_cascade_name = opencv_path + "/data/haarcascades_cuda/haarcascade_fullbody.xml";
  295.  
  296. cout << "head and Shoulder Cascade Name" << upperbody_cascade_name << "Colored GREEN Rectangle" << endl;
  297. cout << "lowerbody_cascade_name" << cuda_lowerbody_cascade_name << "Colored BLUE Rectangle" << endl;
  298. cout << "fullbody_cascade_name" << cuda_fullbody_cascade_name << "Colored RED Rectangle" << endl;
  299.  
  300. //Load the GPU/CUdA Compliant video cascaders
  301. cascade_gpu_upperbody = cuda::CascadeClassifier::create(upperbody_cascade_name);
  302. cascade_gpu_lowerbody = cuda::CascadeClassifier::create(cuda_lowerbody_cascade_name);
  303. cascade_gpu_fullbody = cuda::CascadeClassifier::create(cuda_fullbody_cascade_name);
  304. cout << "Created the CUDA HAAR Classifiers" << endl;
  305. }
  306.  
  307. }
  308. else //use CPU
  309. {
  310.  
  311. if (useAlgo == "haar") {
  312.  
  313. //The below are the path to the HAAR trained casrcades
  314. //The below taken from http://alereimondo.no-ip.org/OpenCV/34.version?id=60 ; not for commercial use
  315. String upperbody_cascade_name = opencv_path + "/data/HS22x20/HS.xml"; //head and sholders
  316. //String lowerbody_cascade_name = opencv_path + "/data/haarcascades/haarcascade_lowerbody.xml";
  317. String lowerbody_cascade_name = opencv_path + "/data/haarcascades/haarcascade_frontalface_alt_tree.xml";
  318. String fullbody_cascade_name = opencv_path + "/data/haarcascades/haarcascade_fullbody.xml";
  319.  
  320. cout << "head and Shoulder Cascade Name" << upperbody_cascade_name << "Colored GREEN Rectangle" << endl;
  321. cout << "lowerbody_cascade_name" << lowerbody_cascade_name << "Colored BLUE Rectangle" << endl;
  322. cout << "fullbody_cascade_name" << fullbody_cascade_name << "Colored RED Rectangle" << endl;
  323.  
  324. //-- 1. Load the cascades
  325. if (!upperbody_cascade.load(upperbody_cascade_name)) {
  326. printf("--(!)Error loading UpperBody\n");
  327. return -1;
  328. };
  329. if (!lowerbody_cascade.load(lowerbody_cascade_name)) {
  330. printf("--(!)Error loading lowerbody \n");
  331. return -1;
  332. };
  333.  
  334. if (!fullbody_cascade.load(fullbody_cascade_name)) {
  335. printf("--(!)Error loading fullbody\n");
  336. return -1;
  337. };
  338.  
  339. cout << "Created the HAAR Classifiers" << endl;
  340. }
  341. else //use hog
  342. {
  343. cpu_hog.setSVMDetector(cv::HOGDescriptor::getDaimlerPeopleDetector());
  344. cout << "Set the HOG Classifiers" << endl;
  345. }
  346. }
  347.  
  348.  
  349. double delay = lexical_cast<double>(getPropertyVal("config.ini","GENERAL.DELAY"));
  350. cout << "Delay is " << delay << endl;
  351. clock_t startTimeG = clock();
  352. bool doLoop = true;
  353. while (doLoop)
  354. {
  355. Mat frame, resized;
  356.  
  357. bool bSuccess = cap.read(frame); // read a new frame from video
  358. if (!bSuccess) //if not success, break loop
  359. {
  360. cout << "Cannot read the frame from video file" << endl;
  361. doLoop = false;
  362. break;
  363. }
  364. counter_frames_processed += 1;
  365.  
  366. cv::resize(frame, resized, downFrameSize);// resize the frame to something smaller- makes computatin faster
  367. if (useAlgo == "hog") {
  368. detectAndDisplayHOG(resized, oVideoWriter,useGpu);
  369. }
  370. else //haar
  371. {
  372. detectAndDisplayHAAR(resized, oVideoWriter,useGpu);
  373. }
  374.  
  375. clock_t endTime = clock() + (delay* CLOCKS_PER_SEC); // this is a wrong way ; mabye multipy by CLOCKS_PER_SEC ? leaving it for now
  376. while (clock() < endTime) { // This is the best my card supports
  377. if (cap.read(frame)) { //read only one frame per
  378. counter_frames_skipped += 1;
  379.  
  380.  
  381. }
  382. waitKey(1);
  383. }
  384. cout << "Frames processed = " << counter_frames_processed << " Frames found = "
  385. << counter_frames_detected << " Frames skipped = " << counter_frames_skipped
  386. << " % Time taken =" << (clock() - startTimeG) / CLOCKS_PER_SEC << " seconds"
  387. << " \r" ;
  388. }
  389. oVideoWriter.release();
  390. cout << "Total time taken = " << (clock() - startTimeG) / CLOCKS_PER_SEC << " seconds" << endl;
  391. cout << "counter_frames_processed = " << counter_frames_processed << endl;
  392. cout << "counter_frames_skipped = " << counter_frames_skipped << endl;
  393. cout << "counter_frames_detected = " << counter_frames_detected << endl;
  394. return 0;
  395. }
  396.  
  397. [GENERAL]
  398. # Algorith hog or haar
  399. USE_ALGO=hog
  400. VIDEO_PATH=""
  401. OPENCV_PATH=/home/alex/opencv
  402. OUT_PATH=/tmp/out.avi
  403. USE_GPU=1
  404. REDUCE_FRAME=0
  405. DELAY = 0.05
  406.  
  407. [VIDEO]
  408. VIDEO_DEVICE_ID = 1
  409. CV_CAP_PROP_FRAME_WIDTH=1600
  410. CV_CAP_PROP_FRAME_HEIGHT=896
  411.  
  412. [HAAR]
  413. scalingFactor=1.02
  414. numberOfNeighbours=3
  415. min_cell_size=30
  416.  
  417. [HOG]
  418. scaleFactor = 1.20
  419. hogLevels = 16
  420. win_stride_width = 8
  421. #increase this to 48
  422. hogGroupThreshold =16
  423. # min cell size 8 to 30
  424. min_cell_size=4
Add Comment
Please, Sign In to add comment