-3

비디오를 읽는 opencv 코드를 작성하고 각 프레임에서 빨간색 픽셀을 찾은 다음 빨간색 픽셀 수가 특정 양을 초과하면 프레임을 png 파일로 내 보냅니다 . 코드는 잘 작동하지만 비디오의 길이가 4-5 시간이므로 계산 시간을 줄이는 방법을 찾고 있습니다. parallel_pipeline을 사용하여 게시물을 읽었을 때 프로세스 사용 속도가 상당히 빨라 졌는지 궁금합니다. 내가 읽은 것을 바탕으로 각 주요 작업 (비디오 프레임 읽기, 색상 감지/inRange를 통한 임계 값 설정, 이미지 저장)마다 스레드를 지정해야하는 것 같습니다. 그래서 제 질문은 :계산 시간을 줄이기 위해 코드를 더 잘 스레드하는 방법

1) opencv가 수행하는 기본 멀티 스레딩과 비교하여 프로세스가 빨라 집니까?

2) 코드가 수행해야하는 것을 감안할 때 parallel_pipeline보다 멀티 스레딩을위한 적절한 방법이 있습니까?

나는이 주제에 대해 상당히 새로운 것이므로 어떤 도움이라도 대단히 감사합니다!

waitKey(10); 

그런 '\n'endl 교체 :

/** 
* @CheckMotionParallel 
* @Motion detection using color detection and image thresholding 
*/ 

//opencv 
#include "opencv2/imgcodecs.hpp" 
#include "opencv2/imgproc.hpp" 
#include "opencv2/videoio.hpp" 
#include <opencv2/highgui.hpp> 
#include <opencv2/video.hpp> 
//C 
#include <stdio.h> 
//C++ 
#include <iostream> 
#include <sstream> 
#include "tbb/blocked_range.h" 
#include "tbb/parallel_for.h" 
#include "tbb/parallel_reduce.h" 
#include "tbb/task_scheduler_init.h" 
#include "tbb/mutex.h" 
#include "tbb/tbb_thread.h" 
#include "tbb/blocked_range2d.h" 

using namespace cv; 
using namespace std; 
using namespace tbb; 

void help(); 
void help() 
{ 
    cout 
    << "--------------------------------------------------------------------------" << endl 
    << "Note for program CheckMotion" << endl 
    << "CheckMotion does the following" << endl 
    << "1) It searches each frame in a video and looks for a specified range of colors in the frame"                 << endl 
    << "2) Pixels falling within the range will be converted to white while everything else is turned to black"      << endl 
    << "3) For each frame, the program gives: frame number/time stamp, total pixel count, and white pixel count"          << endl 
    << "4) For frames whose white pixel count exceeds a threshold, it will export those frames as individial png files" << endl 
    << "--------------------------------------------------------------------------" << endl 
    << endl; 
} 

int64 startTime; 

int NumThreads = task_scheduler_init::default_num_threads(); 

int main(int argc, char**) 
{ 
    //Print out program note 
    help(); 

    ///Part I: Read-in the video 

    VideoCapture cap("/Users/chi/Desktop/Video analyses/testvideo4.mp4"); 

    //Error message if the video cannot be opened 
    //Create an object denoting the frames 
    //Create a window for showing the video as CheckMotion runs 
    //For loop looking through frames 

    if(cap.isOpened()) { 

     startTime = getTickCount(); 

     Mat frame; 
     for(;;) 
     { 
      //Show each frame in the video window previously created 
      double tfreq = getTickFrequency(); 
      double secs = ((double) getTickCount()-startTime)/tfreq; 

      cap >> frame; 

      //   namedWindow("Frame"); 
      //   imshow("Frame",frame); 
      // 
      waitKey(10); 
      //Create a string for frame number that gets updated for each cycle of the loop 
      stringstream ss; 
      ss << cap.get(CAP_PROP_POS_FRAMES); 
      string FrameNumberString = ss.str(); 

      stringstream maskedfilename; 
      stringstream rawfilename; 
      //Create filenames for later use in result output and image save using frame number as ref 
      maskedfilename << "/Users/chi/Desktop/test/masked" << FrameNumberString.c_str() << ".png"; 
      rawfilename << "/Users/chi/Desktop/test/raw" << FrameNumberString.c_str() << ".png"; 

      ///Part II: Image thresholding and image saving 

      //Create an object representing new images after thresholding 
      Mat masked; 
      //inRange function that convert the pixels that fall within the specified range to white and everything else to black 
      //The Range is specified by a lower [Scalar(200,200,200)] and an upper [Scalar(255,255,255)] threshold 
      //A color is defined by its BGR score 
      //The thresholded images will then be represented by the object "masked" 
      inRange(frame, Scalar(10,0,90), Scalar(50,50,170), masked); 

      //Creating integer variables for total pixel count and white pixel count for each frame 
      int totalpixel; 
      int whitepixel; 

      //Total pixel count equals the number of rows and columns of the frame 
      totalpixel = masked.rows*masked.cols; 
      //Using countNonZero function to count the number of white pixels 
      whitepixel = countNonZero(masked); 
      //Output frame number, total pixel count and white pixel count for each frame 

      //Exit the loop when reaching the last frame (i.e. pixel count drops to 0) 
      if(totalpixel==0){ 
       cout << "End of the video" << endl; 
       cout << "Number of threads: " << NumThreads << endl; 
       cap.release(); 
       break; 
      } 

      else { 
       cout 
       << "Frame:" << ss.str() << endl 
       << "Number of total pixels:" << totalpixel << endl 
       << "Pixels of target colors:" << whitepixel << endl 
       << "Run time = " << fixed << secs << "seconds" << endl 
       << endl; 
       //Save the frames with white pixel count larger than a user-determined value (100 in present case) 
       //Save both the orignal as well as the procesed images 
       if (whitepixel > 50){ 
       imwrite(rawfilename.str(),frame); 
       imwrite(maskedfilename.str(),masked); 
       } 
      } 
     } 
    } 
} 
+3

프로파일 러를 사용하여 병목 현상을 확인한 다음 해결합니다. –

+0

감사 캡틴 분명! 나는 그것을 조사 할 것이다. – Chi

답변

1

그냥이 줄을 제거합니다.