-3
我寫了一個opencv代碼,它讀取一個視頻,在每一幀中查找紅色像素,並在紅色像素數超過一定數量時將幀導出爲png文件。代碼運行良好,但我正在尋找進一步減少計算時間的方法,因爲視頻長度爲4-5小時。我正在閱讀關於使用parallel_pipeline的文章,並想知道如果使用它會大大加快進程。根據我閱讀的內容,似乎我將不得不爲每項主要任務分配一個線程(讀取視頻幀,使用inRange進行顏色檢測/閾值處理以及保存圖像)。所以我的問題是:更好的線程代碼以減少計算時間的方法
1)與opencv默認的多線程相比,這會加快進程嗎?
2)鑑於代碼需要做什麼,是否有比parallel_pipeline更適合多線程的方式?
我對這個主題相當陌生,所以任何幫助都非常感謝!
/**
* @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);
}
}
}
}
}
使用分析器確定瓶頸然後解決它們。 –
謝謝隊長明顯!我會仔細看看的。 – Chi