更好地线程化代码以减少计算时间的方法[关闭]

Posted

技术标签:

【中文标题】更好地线程化代码以减少计算时间的方法[关闭]【英文标题】:Ways to better thread the code to decrease computation time [closed] 【发布时间】:2017-10-06 15:32:07 【问题描述】:

我编写了一个 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);
                
            
        
    

【问题讨论】:

使用分析器识别瓶颈,然后解决它们。 感谢明显队长!我会调查的。 【参考方案1】:

只需删除这一行:)

waitKey(10);

然后将endl 替换为'\n'

【讨论】:

以上是关于更好地线程化代码以减少计算时间的方法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

并行化大型动态程序

当计算使用后台线程时,如何正确声明计算属性?

计算乘法为完美平方的所有可能对的有效算法[关闭]

halcon算子并行和串行计算

python多线程并行计算通过向线程池ThreadPoolExecutor提交任务的实现方法

有效地计算两个向量之间的差异