1

我正在使用 FLIR 的 USB 摄像头,并对每个捕获的帧进行一些处理。

不幸的是,我设法每秒只处理 10 帧(甚至在“调试”配置中运行时甚至 5 帧)。

我怎样才能提高性能?

PC:英特尔酷睿 i5-5200u (Broadwell) 2.7GHz 8 GB RAM

操作系统:Windows 10

语言:c++

图像处理库:openCV ver 3.4.0

对比:2015 (vc14)

FLIR API:三角帆

这是我的代码:

#include <iostream>
#include "Spinnaker.h"
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;
using namespace Spinnaker;

#define GAUSSIAN_SIZE               11

Mat ConvertToCVmat(ImagePtr pImage)
{
    int result = 0;
    ImagePtr convertedImage = pImage->Convert(PixelFormat_BGR8, NEAREST_NEIGHBOR);

    unsigned int XPadding = static_cast<unsigned int>(convertedImage->GetXPadding());
    unsigned int YPadding = static_cast<unsigned int>(convertedImage->GetYPadding());
    unsigned int rowsize = static_cast<unsigned int>(convertedImage->GetWidth());
    unsigned int colsize = static_cast<unsigned int>(convertedImage->GetHeight());

    //image data contains padding. When allocating Mat container size, you need to account for the X,Y image data padding. 
    Mat cvimg = cv::Mat(colsize + YPadding, rowsize + XPadding, CV_8UC3, convertedImage->GetData(), convertedImage->GetStride());
    return cvimg.clone();
}

void measureTime(void)
{
    static int frameNumber = 0;
    frameNumber++;
    if (frameNumber == 24)
    {
        static int64 e2 = 1;
        static int64 e1 = 0;
        e2 = getTickCount();
        double time = (e2 - e1) / getTickFrequency();
        e1 = getTickCount();
        printf("Proccessed %d frames in %f seconds\n", frameNumber, time);
        frameNumber = 0;
    }
}

void run(CameraPtr pCam)
{
    // Initialize camera
    pCam->Init();

    // Set trigger off, software, and then on again: 
    pCam->TriggerMode.SetValue(TriggerModeEnums::TriggerMode_Off);
    pCam->TriggerSource.SetValue(TriggerSourceEnums::TriggerSource_Software);
    pCam->TriggerMode.SetValue(TriggerModeEnums::TriggerMode_On);

    // Set aqcuisition mode to continuous and start: 
    pCam->AcquisitionMode.SetValue(AcquisitionModeEnums::AcquisitionMode_Continuous);
    pCam->BeginAcquisition();

    // Retrieve the next image:
    namedWindow("image", CV_WINDOW_NORMAL);
    while (1)
    {
        pCam->TriggerSoftware.Execute();
        ImagePtr pResultImage = pCam->GetNextImage();

        // convert to openCV format
        Mat frame = ConvertToCVmat(pResultImage);
        pResultImage->Release();

        // convert to one channel
        cvtColor(frame, frame, COLOR_RGB2GRAY);

        // Gaussian blur:
        Mat imageProc1 = frame;
        GaussianBlur(frame, imageProc1, Size(GAUSSIAN_SIZE, GAUSSIAN_SIZE), 0, 0);

        // find max value:
        double minValue, maxValue;
        Point minIndex, maxIndex;
        minMaxLoc(imageProc1, &minValue, &maxValue, &minIndex, &maxIndex);

        // Draw circles: 
        circle(imageProc1, maxIndex, 29, Scalar(0, 0, 255), 3);

        // Measure time:
        measureTime();

        imshow("image", imageProc1);

        if (waitKey(1) >= 0)
        {
            break;
        }
    }

    // Deinitialize camera
    pCam->EndAcquisition();
    pCam->DeInit();
}

int main()
{
    // Retrieve singleton reference to system object
    SystemPtr system = System::GetInstance();

    // Retrieve list of cameras from the system
    CameraList camList = system->GetCameras();

    // Retrieve pointer for the camera: 
    run(camList.GetByIndex(0));

    // Clear camera list before releasing system
    camList.Clear();
    // Release system
    system->ReleaseInstance();
}
4

1 回答 1

0

图像处理(尤其是批处理)是多线程的典型用例。

多线程提供了巨大的速度提升,因为可以一次处理多个图像(最多您机器的核心数)。当然,您使用的库必须是明确的线程安全的(我不知道 OpenCV 是否是这种情况,请参阅手册 - 但我认为是的,因为库现在没有多大意义线程安全。不过,其中一些需要特殊定义来编译线程安全),而且您自己的代码也必须是线程安全的。线程安全的。这不是很容易学习,但绝对值得努力。

实现高速的另一种方法是将 GPU 用于此类任务。GPU 是高度并行的,甚至比 CPU 上的多线程还要快。您使用的库必须支持 GPU 处理(再次,请参阅手册),或者您必须自己编写 GPU 代码(例如使用OpenCL)。您将需要具有良好 GPU 的强大显卡。

于 2018-02-01T07:38:51.537 回答