我进行以下测试,但是结果不是很好,因为我希望GAPI可以有所改善。我不知道我做错了什么,希望您能帮助我纠正,非常感谢!



#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/imgproc.hpp>

std::string image_path = "1.png";
cv::Mat GAPITEST(const cv::Mat& input_frame)
{
    cv::Mat output_frame;

    cv::GMat in;
    cv::GMat vga = cv::gapi::resize(in, cv::Size(), 0.5, 0.5);
    cv::GMat gray = cv::gapi::BGR2Gray(vga);
    cv::GMat blurred = cv::gapi::blur(gray, cv::Size(5, 5));
    cv::GMat out = cv::gapi::Canny(blurred, 32, 128, 3);
    cv::GComputation ac(in, out);

    int64 t0 = cv::getTickCount();
    for(int i=0;i<200;i++)
        ac.apply(input_frame, output_frame);
    int64 t1 = cv::getTickCount();
    std::cout <<__func__<< "\t seconds:" << (t1 - t0) / cv::getTickFrequency()<<std::endl;

    return output_frame;
}

cv::Mat TraditionalTEST(const cv::Mat& input_frame)
{
    cv::Mat output_frame;
    cv::Mat vga;
    cv::Mat gray;
    cv::Mat blurred;

    int64 t0 = cv::getTickCount();
    for (int i = 0; i < 200; i++)
    {
        cv::resize(input_frame,vga, cv::Size(), 0.5, 0.5);
        cv::cvtColor(vga, gray, cv::COLOR_BGR2GRAY);
        cv::blur(gray, blurred,cv::Size(5,5));
        cv::Canny(blurred,output_frame,32,128,3);
    }
    int64 t1 = cv::getTickCount();
    std::cout << __func__ << "\t seconds:" << (t1 - t0) / cv::getTickFrequency()<<std::endl;
    return output_frame;
}
int main()
{
    cv::Mat input_frame = cv::imread(image_path);
    cv::imshow("input_frame",input_frame);
    cv::waitKey(100);
    auto result1 = GAPITEST(input_frame);
    auto result2 = TraditionalTEST(input_frame);
    //check result whether identical or not.
    bool eq = cv::countNonZero(result1 != result2) == 0;
    std::cout << "result equal  "<< eq;
    return 0;
}


出路
GAPITEST         seconds:4.92153
TraditionalTEST  seconds:4.68761
result equal  1

最佳答案

GAPI仍处于早期开发阶段,其在单台计算机上的性能非常差。 GAPI本身并非主要用于直接计算算法,因此它使用后端库执行计算。默认值为OpenCV的默认后端,很糟糕。您可以将其替换为Fluid后端,该后端在执行算法时据说具有更好的缓存位置,但是在我的一些测试中仍然很糟糕。

这些后端缺乏基本的OpenCV功能实现(例如,Fluid仅支持3x3内核用于盒式过滤器),并且当您使用不受支持的操作时,GComputation::apply会意外崩溃,并且经常没有任何有用的错误消息。

GAPI的优点在于它实现的图形模型与硬件无关。您可以将其生成的图形放入具有多个GPU,CPU的云或分布式计算系统中,并随便使用它,它将充分利用自动可用的资源。

如果要在一台计算机上实现快速性能,建议使用cv::cuda::GpuMat。我本人经常使用此功能,并且它在许多操作中快速发展。它省去了编写自定义CUDA内核的麻烦。

我不能保证UMat或其他GPU的实现质量,因为我只将OpenCV与Nvidia卡一起使用。

您还可以考虑使用OpenMP支持编译OpenCV以提高性能。

无论如何,这就是a弹枪的答案。请转到此处,获取有关GAPI的更多详细信息以及比较多个后端的更完整的测试程序:https://docs.opencv.org/master/d3/d7a/tutorial_gapi_anisotropic_segmentation.html

关于c++ - OpenCV GAPI性能不如预期的好,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60629331/

10-09 13:32