Advertisement
Guest User

Untitled

a guest
Jan 18th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.59 KB | None | 0 0
  1. #include "opencv2/objdetect.hpp"
  2. #include "opencv2/imgcodecs.hpp"
  3. #include "opencv2/videoio.hpp"
  4. #include "opencv2/highgui.hpp"
  5. #include "opencv2/face.hpp"
  6. #include "opencv2/imgproc.hpp"
  7. #include "opencv2/core/utility.hpp"
  8. #include "opencv2/core/core_c.h"
  9. #include "opencv2/videoio/videoio_c.h"
  10. #include "opencv2/highgui/highgui_c.h"
  11. #include <opencv2/video/background_segm.hpp>
  12. #include <opencv2/video/tracking.hpp>
  13. #include <opencv2/core/ocl.hpp>
  14.  
  15. #include <cctype>
  16. #include <iostream>
  17. #include <iterator>
  18. #include <stdio.h>
  19. #include <deque>
  20. #include <set>
  21. #define FACE_SIZE 128
  22. #define FACE_DETECT_MIN_SIZE 90
  23. #define EYE_DETECT_MIN_SIZE 10
  24.  
  25. #define FACE_THRESHOLD 80.0
  26. #define MAX_FACE_IMAGES 15
  27. #define MAX_FEATURE_ERROR 10
  28. #define FACE_CONFIRMATION_TIME 30
  29. #define FACE_CONFIRMATION_COUNT 2
  30. #define FACE_EXPIRY_TIME 100
  31. #define CORNER_EXPIRY_TIME 5
  32. #define OVERLAP_FORCE_MATCH_DIST 100
  33. #define OVERLAP_FORCE_MATCH_TIME 20
  34. #define TRANSPOSE 0
  35.  
  36. using namespace std;
  37. using namespace cv;
  38.  
  39. string cascadeName = "data/haarcascades/haarcascade_frontalface_alt.xml";
  40. string eyesName = "data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
  41. string noseName = "data/haarcascades/haarcascade_mcs_nose.xml";
  42. string mouthName = "data/haarcascades/haarcascade_mcs_mouth.xml";
  43.  
  44. struct Face {
  45. int id;
  46. Rect rect;
  47. Mat img;
  48. deque<Mat> faceImgs;
  49. Rect imgRect;
  50. vector<Point2f> corners;
  51. vector<int> cornerFrames;
  52. vector<Point2f> trail;
  53. int lastMatch;
  54. int firstFrame;
  55. int lastFrame;
  56. int nestedCount;
  57.  
  58. public:
  59. void pushTrail(const Point2f& p) {
  60. trail.push_back(p);
  61. }
  62. void pushTrail(const Rect& r) {
  63. pushTrail(Point2f(r.x + r.width / 2, r.y + r.height / 2));
  64. }
  65. Face(int id_, const Rect& r, const Mat& i, const Mat& fi, const Rect& ir, const vector<Point2f>& cs, int num, int nestedCount_)
  66. : id(id_), rect(r), img(i), imgRect(ir), corners(cs), firstFrame(num), lastFrame(num), nestedCount(nestedCount_) {
  67. pushTrail(r);
  68. faceImgs.push_back(fi);
  69. lastMatch = num;
  70. cornerFrames.resize(corners.size());
  71. for (vector<int>::iterator cf = cornerFrames.begin(); cf != cornerFrames.end(); cf++)
  72. *cf = num;
  73. }
  74. };
  75. class Detector {
  76. vector<Face> faces;
  77. Mat gray;
  78. int nextId;
  79. Ptr<cv::face::FaceRecognizer> recognizer;
  80. bool trained;
  81. Rect detectArea;
  82.  
  83.  
  84.  
  85. bool overlapsFace(const Rect& r) {
  86. for (vector<Face>::iterator f = faces.begin(); f != faces.end(); f++) {
  87. Rect i = r & f->rect;
  88. if (i.width > 0)
  89. return true;
  90. }
  91. return false;
  92. }
  93. vector<Face>::iterator closestFace(const Point& p) {
  94. double d = 100000;
  95. vector<Face>::iterator res = faces.end();
  96. for (vector<Face>::iterator f = faces.begin(); f != faces.end(); f++) {
  97. if (f->rect.contains(p)) {
  98. Point c(f->rect.x + f->rect.width / 2, f->rect.y + f->rect.height / 2);
  99. double dist = cv::norm(p-c);
  100. if (dist < d && dist < OVERLAP_FORCE_MATCH_DIST) {
  101. d = dist;
  102. res = f;
  103. }
  104. }
  105. }
  106. return res;
  107. }
  108.  
  109.  
  110. Rect makeImgRect(Rect r) {
  111. Rect imgRect = r;
  112. imgRect.x -= imgRect.width/2;
  113. imgRect.y -= imgRect.height/2;
  114. imgRect.width *= 2;
  115. imgRect.height *= 2;
  116. if (imgRect.x < 0)
  117. imgRect.x = 0;
  118. if (imgRect.y < 0)
  119. imgRect.y = 0;
  120. if (imgRect.x + imgRect.width > gray.cols)
  121. imgRect.width = gray.cols - imgRect.x;
  122. if (imgRect.y + imgRect.height > gray.rows)
  123. imgRect.height = gray.rows - imgRect.y;
  124. return imgRect;
  125. }
  126.  
  127. void drawFaces(Mat& screen) {
  128. int y = 0,x;
  129. vector<pair<Mat, Rect> > copies;
  130. for (vector<Face>::const_iterator f = faces.begin(); f != faces.end(); f++) {
  131. x = 0;
  132. for (deque<Mat>::const_iterator fi = f->faceImgs.begin(); fi != f->faceImgs.end(); fi++) {
  133. Rect dst(x*FACE_SIZE/2, y*FACE_SIZE/2, FACE_SIZE/2, FACE_SIZE/2);
  134. copies.push_back(make_pair(*fi, dst));
  135. x++;
  136. }
  137. y++;
  138. }
  139.  
  140. for (size_t i = 0; i < copies.size(); i++) {
  141.  
  142. Mat roi = screen(copies[i].second);
  143. Mat src;
  144. cvtColor(copies[i].first, src, CV_GRAY2RGB);
  145. resize(src,src, Size(), 0.5, 0.5);
  146. src.copyTo(roi);
  147. }
  148. }
  149. void updateFaces() {
  150. vector<Mat> images;
  151. vector<int> labels;
  152. for (vector<Face>::const_iterator f = faces.begin(); f != faces.end(); f++) {
  153. for (deque<Mat>::const_iterator fi = f->faceImgs.begin(); fi != f->faceImgs.end(); fi++) {
  154. images.push_back(*fi);
  155. labels.push_back(f->id);
  156. }
  157. }
  158. if (images.empty())
  159. return;
  160.  
  161. if (!trained) {
  162. recognizer->train(images, labels);
  163. trained = true;
  164. } else {
  165. // recognizer->update(images, labels);
  166. recognizer->train(images, labels);
  167. }
  168. }
  169.  
  170. void cropAndResizeFaceImage(Mat& face) {
  171. Rect r;
  172. r.width = min(face.cols, face.rows);
  173. r.height = min(face.cols, face.rows);
  174. r.x = (face.cols - r.width) / 2;
  175. r.y = (face.rows - r.height) / 2;
  176. Mat tmp = face(r);
  177. cv::resize(tmp, face, cv::Size(FACE_SIZE, FACE_SIZE));
  178.  
  179.  
  180. }
  181. void forceMatchFace(vector<Face>::iterator f, const Rect& r, const Mat& roiColor, const Mat& roi, const Mat& faceImg, const Rect& imgRect,
  182. const vector<Point2f>& corners, int num, int nestedCount) {
  183. char buf[32];
  184. snprintf(buf, 32, "faces/%02d-%04d.jpg", f->id, num);
  185. imwrite(buf, roiColor);
  186. f->rect = r;
  187. f->img = roi;
  188. f->faceImgs.push_back(faceImg);
  189. if (f->faceImgs.size() > MAX_FACE_IMAGES) {
  190. f->faceImgs.pop_front();
  191. }
  192. f->imgRect = imgRect;
  193. f->corners = corners;
  194. f->cornerFrames.resize(corners.size());
  195. f->nestedCount += nestedCount;
  196. f->pushTrail(r);
  197. for (vector<int>::iterator cf = f->cornerFrames.begin(); cf != f->cornerFrames.end(); cf++)
  198. *cf = num;
  199. f->lastFrame = num;
  200. }
  201. bool matchFace(const Rect& r, const Mat& roiColor, const Mat& roi, const Mat& faceImg, const Rect& imgRect,
  202. const vector<Point2f>& corners, int num, int foundNested) {
  203. int label;
  204. double confidence;
  205. recognizer->predict(faceImg, label, confidence);
  206. cerr << "match label = " << label << endl;
  207. cerr << "condidence = " << confidence << endl;
  208. cerr << "nested count = " << foundNested << endl;
  209. for (vector<Face>::iterator f = faces.begin(); f != faces.end(); f++) {
  210. if (f->id == label) {
  211. forceMatchFace(f, r, roiColor, roi, faceImg, imgRect, corners, num, foundNested);
  212. return true;
  213. }
  214. }
  215. return false;
  216. }
  217.  
  218. CascadeClassifier cascade;
  219. CascadeClassifier eyes;
  220. CascadeClassifier mouth;
  221. CascadeClassifier nose;
  222. public:
  223.  
  224. Detector() : nextId(1),
  225. recognizer(cv::face::createLBPHFaceRecognizer(1,8,8,8, FACE_THRESHOLD)), trained(false) {
  226.  
  227. cascade.load( cascadeName );
  228. eyes.load(eyesName);
  229. mouth.load(mouthName);
  230. nose.load(noseName);
  231. }
  232.  
  233. void setDetectArea(const Rect& detectArea_) {
  234. detectArea = detectArea_;
  235. }
  236. void adjustDetectArea(double x, double y, bool topLeft) {
  237. if (topLeft) {
  238. detectArea.width -= x - detectArea.x;
  239. detectArea.height -= y - detectArea.y;
  240. detectArea.x = x;
  241. detectArea.y = y;
  242. } else {
  243. detectArea.width = x - detectArea.x;
  244. detectArea.height = y - detectArea.y;
  245. }
  246. }
  247. int nestedDetect(const Rect& r, Mat& img, const Mat& face, CascadeClassifier& cc, const string& name) {
  248. vector<Rect> bonusRects;
  249. cout << "detecting " << name << endl;
  250. cc.detectMultiScale(face, bonusRects,
  251. 1.1, 2 , 0
  252. //|CASCADE_FIND_BIGGEST_OBJECT
  253. //|CASCADE_DO_ROUGH_SEARCH
  254. |CASCADE_SCALE_IMAGE
  255. ,
  256. Size(EYE_DETECT_MIN_SIZE, EYE_DETECT_MIN_SIZE) );
  257. cout << "Found " << bonusRects.size() << " " << name << endl;
  258.  
  259. for (vector<Rect>::iterator er = bonusRects.begin(); er != bonusRects.end(); er++) {
  260. er->x += r.x;
  261. er->y += r.y;
  262. rectangle( img, cvPoint(cvRound(er->x), cvRound(er->y)),
  263. cvPoint(cvRound((er->x + er->width-1)), cvRound((er->y + er->height-1))),
  264. CV_RGB(255,255,0), 2, 8, 0);
  265. }
  266. return bonusRects.size();
  267.  
  268. }
  269. void detectAndDraw( int num, Mat& img, Mat& imgHsv, VideoWriter& writer)
  270. {
  271. int i = 0;
  272. double t = 0;
  273. vector<Rect> rects;
  274.  
  275. Mat orig = img.clone();
  276. bool facesChanged = false;
  277. const static Scalar colors[] = { CV_RGB(0,0,255),
  278. CV_RGB(0,128,255),
  279. CV_RGB(0,255,255),
  280. CV_RGB(0,255,0),
  281. CV_RGB(255,128,0),
  282. CV_RGB(255,255,0),
  283. CV_RGB(255,0,0),
  284. CV_RGB(255,0,255)} ;
  285.  
  286. cvtColor( img, gray, COLOR_BGR2GRAY );
  287. equalizeHist( gray, gray );
  288. int maxCorners = 64;
  289. double qualityLevel = 0.01;
  290. double minDistance = 5;
  291. int blockSize = 3;
  292. vector<cv::Point2f> corners;
  293.  
  294. int win_size = 15;
  295.  
  296.  
  297. t = (double)cvGetTickCount();
  298. if (num%5==0) {
  299. Rect r = detectArea;
  300. rectangle(img, Point(r.x, r.y), Point(r.x+r.width, r.y+r.height), colors[4], 1, 8, 0);
  301. cout << "detecting faces" << endl;
  302. cascade.detectMultiScale( gray(detectArea), rects,
  303. 1.05, 3, 0
  304. //|CASCADE_FIND_BIGGEST_OBJECT
  305. //|CASCADE_DO_ROUGH_SEARCH
  306. |CASCADE_SCALE_IMAGE
  307. ,
  308. Size(FACE_DETECT_MIN_SIZE, FACE_DETECT_MIN_SIZE) );
  309. t = (double)cvGetTickCount() - t;
  310. printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
  311. for( vector<Rect>::iterator r = rects.begin(); r != rects.end(); r++, i++ )
  312. {
  313. cout << "face of size " << r->width << "x" << r->height << endl;
  314. r->x += detectArea.x;
  315. r->y += detectArea.y;
  316. Point center;
  317. Scalar color = colors[i%8];
  318. float skinSum=0;
  319. for (int y=r->y; y<r->y+r->height; y++)
  320. {
  321. for (int x=r->x; x<r->x+r->width; x++)
  322. {
  323. Vec3b bgr = img.at<Vec3b>(y, x);
  324. Vec3b hsv = imgHsv.at<Vec3b>(y, x);
  325. float cb = 0.148*bgr.val[2] - 0.291*bgr.val[1] + 0.439*bgr.val[0] + 128;
  326. float cr = 0.439*bgr.val[2] - 0.368*bgr.val[1] - 0.071*bgr.val[0] + 128;
  327. if ( ( hsv.val[0]>245 || hsv.val[0]<25.5) && 140<=cr && cr<=165 && 140<=cb && cb<=195)
  328. {
  329. skinSum++;
  330. }
  331. }
  332. }
  333. //if less than 30% skin, this face doesnt count
  334. if (skinSum / (r->width*r->height) < 0.3)
  335. {
  336. continue;
  337. //break;
  338. }
  339.  
  340. Mat faceImg = gray(*r).clone();
  341. int eyesCount = nestedDetect(*r, img, faceImg, eyes, "eyes");
  342. // nestedDetect(*r, img, faceImg ,mouth, "mouth");
  343. int noseCount = nestedDetect(*r, img, faceImg, nose, "nose");
  344. int nestedCount = eyesCount + noseCount;
  345. cropAndResizeFaceImage(faceImg);
  346.  
  347. Rect imgRect = makeImgRect(*r);
  348. Mat roi = gray(imgRect).clone();
  349. Mat roiColor = orig(*r).clone();
  350. Rect maskRect = *r;
  351. maskRect.x -= imgRect.x;
  352. maskRect.y -= imgRect.y;
  353. Mat mask = cv::Mat::zeros(imgRect.height, imgRect.width, CV_8U);
  354. mask(maskRect) = 1;
  355. cv::goodFeaturesToTrack(roi, corners, maxCorners, qualityLevel, minDistance, mask, blockSize, false, 0);
  356. if (corners.empty())
  357. continue;
  358.  
  359. cornerSubPix( roi, corners, Size( win_size, win_size ), Size( -1, -1 ),
  360. TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ) );
  361.  
  362. for (size_t i = 0; i < corners.size(); i++) {
  363. Point center = corners[i];
  364. center.x += imgRect.x;
  365. center.y += imgRect.y;
  366. circle(img, center, 2, colors[2], 1, 8, 0);
  367. }
  368.  
  369. if (trained && matchFace(*r, roiColor, roi, faceImg, imgRect, corners, num, nestedCount)) {
  370. facesChanged = true;
  371. continue;
  372. } else {
  373. if (!trained) {
  374. cout << "not trained" << endl;
  375. }
  376. }
  377. Point middle(r->x + r->width / 2, r->y + r->height / 2);
  378. vector<Face>::iterator o = closestFace(middle);
  379. if (o != faces.end()) {
  380. if (num - o->lastMatch < OVERLAP_FORCE_MATCH_TIME) {
  381. cout << "forcing match!" << endl;
  382. forceMatchFace(o, *r, roiColor, roi, faceImg, imgRect, corners, num, nestedCount);
  383. facesChanged = true;
  384. }
  385. continue;
  386. }
  387. if (overlapsFace(*r)) {
  388. cout << "overlaps with a face. not doing anything" << endl;
  389. continue;
  390. }
  391. faces.push_back(Face(nextId++, *r, roi, faceImg, imgRect, corners, num, nestedCount));
  392. facesChanged = true;
  393.  
  394.  
  395. rectangle( img, cvPoint(cvRound(r->x), cvRound(r->y)),
  396. cvPoint(cvRound((r->x + r->width-1)), cvRound((r->y + r->height-1))),
  397. colors[0], 3, 8, 0);
  398. }
  399. }
  400. for (size_t i = 0; i < faces.size(); ) {
  401. if ((num - faces[i].firstFrame > FACE_CONFIRMATION_TIME
  402. && faces[i].nestedCount < FACE_CONFIRMATION_COUNT)
  403. ||
  404. (num - faces[i].lastFrame > FACE_EXPIRY_TIME)) {
  405. cout << "removing face " << faces[i].id << " nestedCount=" << faces[i].nestedCount << endl;
  406. faces[i] = faces.back();
  407. faces.pop_back();
  408. facesChanged = true;
  409. } else
  410. i++;
  411. }
  412.  
  413. for (vector<Face>::iterator f = faces.begin(); f != faces.end(); f++) {
  414. Point2f prev(0,0);
  415. if (faces[i].nestedCount < FACE_CONFIRMATION_COUNT)
  416. continue;
  417.  
  418. for (vector<Point2f>::iterator p = f->trail.begin(); p != f->trail.end(); p++) {
  419. if (prev.x != 0) {
  420. line( img, prev, *p, CV_RGB(255,0,255), 1 );
  421. }
  422. prev = *p;
  423. }
  424.  
  425. }
  426. for (vector<Face>::iterator f = faces.begin(); f != faces.end(); f++) {
  427.  
  428.  
  429. corners.clear();
  430. Mat roi = gray(f->imgRect);
  431. for (size_t i = 0; i < f->corners.size(); i++) {
  432. if (num - f->cornerFrames[i] > CORNER_EXPIRY_TIME) {
  433. f->cornerFrames[i] = f->cornerFrames.back();
  434. f->corners[i] = f->corners.back();
  435. f->cornerFrames.pop_back();
  436. f->corners.pop_back();
  437. } else
  438. i++;
  439. }
  440.  
  441. if (f->corners.empty())
  442. continue;
  443.  
  444.  
  445. std::vector<uchar> featuresFound;
  446. featuresFound.reserve(maxCorners);
  447. std::vector<float> featureErrors;
  448. featureErrors.reserve(maxCorners);
  449.  
  450. calcOpticalFlowPyrLK( f->img, roi, f->corners, corners, featuresFound, featureErrors ,
  451. Size( win_size, win_size ), 5,
  452. cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3 ), 0 );
  453.  
  454. f->lastFrame = num;
  455.  
  456. Point minP, maxP;
  457. minP.x = 1000;
  458. minP.y = 1000;
  459. maxP.x = 0;
  460. maxP.y = 0;
  461. Point diff;
  462. diff.x = 0;
  463. diff.y = 0;
  464. float numDiffs = 0;
  465. for( size_t i=0; i < featuresFound.size(); i++ ){
  466.  
  467. Point p0( f->imgRect.x + f->corners[i].x , f->imgRect.y + f->corners[i].y );
  468. Point p1( f->imgRect.x + corners[i].x , f->imgRect.y + corners[i].y );
  469. if (!featuresFound[i]) {
  470. continue;
  471. }
  472. if (featureErrors[i] > MAX_FEATURE_ERROR)
  473. continue;
  474.  
  475.  
  476. line( img, p0, p1, CV_RGB(255,255,255), 2 );
  477. f->corners[i] = corners[i];
  478. f->cornerFrames[i] = num;
  479. diff += p1 - p0;
  480.  
  481. if (p1.x < minP.x)
  482. minP.x = p1.x;
  483. if (p1.y < minP.y)
  484. minP.y = p1.y;
  485. if (p1.x > maxP.x)
  486. maxP.x = p1.x;
  487. if (p1.y > maxP.y)
  488. maxP.y = p1.y;
  489. numDiffs++;
  490. }
  491.  
  492. if (numDiffs) {
  493. diff.x /= numDiffs;
  494. diff.y /= numDiffs;
  495.  
  496. f->rect += diff;
  497.  
  498.  
  499. f->imgRect = makeImgRect(f->rect);
  500. f->img = gray(f->imgRect).clone();
  501. }
  502. Rect r = f->rect;
  503. f->pushTrail(r);
  504. int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
  505. double fontScale = 2;
  506. int thickness = 3;
  507. int baseline=0;
  508. rectangle(img, Point(r.x, r.y), Point(r.x+r.width, r.y+r.height), colors[3], 1, 8, 0);
  509. char buf[32];
  510. snprintf(buf, 32, "%d", f->id);
  511. Size textSize = getTextSize(buf, fontFace,
  512. fontScale, thickness, &baseline);
  513. Point textOrg(r.x + r.width / 2 - textSize.width / 2, r.y + r.height / 2 - textSize.width/2);
  514. putText(img, buf, textOrg, fontFace, fontScale,
  515. Scalar::all(255), thickness, 8);
  516.  
  517. }
  518.  
  519. if (facesChanged)
  520. updateFaces();
  521. drawFaces(img);
  522. writer.write(img);
  523.  
  524. cv::resize(img, img, cv::Size(), 0.5, 0.5);
  525.  
  526. cv::imshow( "result", img );
  527. }
  528.  
  529. };
  530.  
  531. void mouseCallback(int event, int x, int y, int flags, void* userdata)
  532. {
  533. Detector* detector = (Detector*) userdata;
  534. if ( event == EVENT_LBUTTONDOWN )
  535. {
  536. cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
  537.  
  538. detector->adjustDetectArea(x*2, y*2, true);
  539. }
  540. else if ( event == EVENT_RBUTTONDOWN )
  541. {
  542. cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
  543. detector->adjustDetectArea(x*2, y*2, false);
  544.  
  545. }
  546. else if ( event == EVENT_MBUTTONDOWN )
  547. {
  548. cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
  549. }
  550. else if ( event == EVENT_MOUSEMOVE )
  551. {
  552. cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;
  553.  
  554. }
  555. }
  556. int main( int argc, const char** argv )
  557. {
  558. cv::ocl::setUseOpenCL(false);
  559. Mat frame, frameCopy, image, frameHsv;
  560. string inputName;
  561. bool tryflip = false;
  562.  
  563.  
  564.  
  565. inputName.assign(argv[1]);
  566.  
  567. Detector detector;
  568. cvNamedWindow( "result", 1 );
  569.  
  570. setMouseCallback("result",mouseCallback, &detector);
  571.  
  572. VideoCapture capture(inputName.c_str());
  573. VideoWriter writer;
  574. Size S = Size((int) capture.get(CV_CAP_PROP_FRAME_WIDTH),
  575. (int) capture.get(CV_CAP_PROP_FRAME_HEIGHT));
  576. if (TRANSPOSE) {
  577. int tmp = S.width;
  578. S.width = S.height;
  579. S.height = tmp;
  580. }
  581. detector.setDetectArea(Rect(0, 0, S.width, S.height));
  582. int ex = static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));
  583. char EXT[] = {(char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0};
  584.  
  585. cout << "Input codec type: " << EXT << endl;
  586. string out = "out-" + inputName.substr(0, inputName.size() -4) + ".mov";
  587. //writer.open(("out" + inputName).c_str(), ex, capture.get(CV_CAP_PROP_FPS), S, true);
  588. writer.open(out.c_str(), cv::VideoWriter::fourcc('m','p','4','v'), capture.get(CV_CAP_PROP_FPS), S, true);
  589.  
  590. if (!writer.isOpened()) {
  591. cerr << "could not open output video" << endl;
  592. return -1;
  593. }
  594. int num;
  595. for(;;)
  596. {
  597. bool done = false;
  598. for (int i = 0; i < 1; i++) {
  599. if (!capture.read(frame)) {
  600. done = true;
  601. break;
  602. }
  603. }
  604. if (done)
  605. break;
  606. if (TRANSPOSE) {
  607. frame = frame.t();
  608. flip(frame, frame,1);
  609. }
  610. cvtColor(frame, frameHsv, CV_BGR2HSV);
  611.  
  612. detector.detectAndDraw( num, frame, frameHsv, writer);
  613. num++;
  614. if( waitKey( 9 ) >= 0 )
  615. goto _cleanup_;
  616. }
  617.  
  618. writer.release();
  619. _cleanup_:
  620. cvDestroyWindow("result");
  621.  
  622. return 0;
  623. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement