C++ 利用MATLAB和OpenCV求和图像的效率

C++ 利用MATLAB和OpenCV求和图像的效率,c++,matlab,opencv,C++,Matlab,Opencv,我对你所有的回答都感到惊讶非常感谢 错误代码如下所示: 百分比=(双)kk*100.0/(双)总数 在我将其修改为: 百分比=(双)kk*100.0/totalnum 问题解决了。这个简单的划分消耗了150个中的90个。也许double和int之间的除法比double之间的除法快 再次感谢您的回答 我试图从一组来自视频的图片中获得平均图像。此作业只有两个步骤: 将所有图像汇总成一个矩阵 将矩阵除以图像数 我在OpenCV中使用了以下代码:(C++) 但当我在2100幅图像上运行这两个程序时,O

我对你所有的回答都感到惊讶非常感谢

错误代码如下所示:
百分比=(双)kk*100.0/(双)总数

在我将其修改为:
百分比=(双)kk*100.0/totalnum

问题解决了。这个简单的划分消耗了150个中的90个。也许double和int之间的除法比double之间的除法快

再次感谢您的回答


我试图从一组来自视频的图片中获得平均图像。此作业只有两个步骤:

  • 将所有图像汇总成一个矩阵
  • 将矩阵除以图像数
  • 我在OpenCV中使用了以下代码:(C++)

    但当我在2100幅图像上运行这两个程序时,OpenCV花费了150.3s(发布版)和MatLab花费了103.1s。我真的很困惑,C++程序运行得比MATLAB脚本慢。p>
    那么是什么让我的OpenCV程序变慢了?如果这是由我的矩阵访问方法引起的,我应该如何提高效率?

    引起我注意的一点是“CV_32FC3”类型。您是否特别喜欢32位浮点矩阵,并且确定Matlab也以相同的方式获取像素值

    因为你有额外的步骤

    tempIM.convertTo(tempIM, CV_32FC3);     
    

    在您的Cpp代码中,Matlab在检索图像时立即直接运行,而不进行任何转换,这可能会降低您的Cpp代码的速度。此外,如果Matlab没有以浮点值获取图像,这可能会导致速度差异,因为浮点运算对CPU来说比整数更难处理

    引起我注意的一点是“CV_32FC3”类型。您是否特别喜欢32位浮点矩阵,并且确定Matlab也以相同的方式获取像素值

    因为你有额外的步骤

    tempIM.convertTo(tempIM, CV_32FC3);     
    

    在您的Cpp代码中,Matlab在检索图像时立即直接运行,而不进行任何转换,这可能会降低您的Cpp代码的速度。此外,如果Matlab没有以浮点值获取图像,这可能会导致速度差异,因为浮点运算对CPU来说比整数更难处理

    您的代码似乎足够好,在我的测试中,我发现它的运行速度比Matlab代码快10倍

    然而,我展示了一个稍微优化的代码,它的执行速度比您的稍快

    注释

    请注意,我没有一个文件夹,名为“你”,所以我在C++版本中使用了<代码> CV::GOLB,在Matlab版本中使用<代码> dir < /Cord>获取文件夹中图像的名称。 在我的文件夹中,我有82个小图像,因此运行时间明显比您的小,但相对性能应该是可靠的

    执行时间

                        Sum only      Get filenames + Sum
    Matlab:             0.173543 s    (0.185308 s)
    OpenCV @Seven Wang: 0.0145206 s   (0.0155748 s)
    OpenCV @Miki:       0.0128943 s   (0.013333 s)
    
    注意事项

    确保在OpenCV和Matlab中一致地计算运行时间


    代码

                        Sum only      Get filenames + Sum
    Matlab:             0.173543 s    (0.185308 s)
    OpenCV @Seven Wang: 0.0145206 s   (0.0155748 s)
    OpenCV @Miki:       0.0128943 s   (0.013333 s)
    
    Matlab代码:

    tic
    
    folder = 'D:\\SO\\temp\\old_075_6\\';
    filenames = dir([folder '*.bmp']);
    
    % Get rows and cols from 1st image
    img = imread([folder name]);
    
    
    
    S = zeros(size(img));
    
    for ii = 1 : length(filenames)
        name = filenames(ii).name;
        currentImage = imread([folder name]);    
        S = S + double(currentImage);
    end
    
    S = uint8(round(S / length(filenames)));
    
    toc
    
    C++代码:

    #include <opencv2\opencv.hpp>
    #include <vector>
    #include <iostream>
    
    int main()
    {
        double ticLoad = double(cv::getTickCount());
    
        std::string folder = "D:\\SO\\temp\\old_075_6\\*.bmp";
        std::vector<cv::String> filenames;
        cv::glob(folder, filenames);
    
        int rows, cols;
        {
            // Just load the first image to get rows and cols
            cv::Mat3b img = cv::imread(filenames[0]);
            rows = img.rows;
            cols = img.cols;
        }
    
        /*{
            double tic = double(cv::getTickCount());
    
            cv::Mat3d S(rows, cols, 0.0);
    
            for (const auto& name : filenames)
            {
                cv::Mat currentImage = cv::imread(name);
                currentImage.convertTo(currentImage, CV_64F);
    
                S += currentImage;
    
            }
            S = S * double(1.0 / filenames.size());
    
            cv::Mat3b avg;
            S.convertTo(avg, CV_8U);
    
            double toc = double(cv::getTickCount());
    
            double timeLoad = (toc - ticLoad) / cv::getTickFrequency();
            double time = (toc - tic) / cv::getTickFrequency();
            std::cout << "@Seven Wang: " << time << " s (" << timeLoad << " s)" << std::endl;
        }*/
    
        {
            double tic = double(cv::getTickCount());
    
            cv::Mat3d S(rows, cols, 0.0);
            cv::Mat3b currentImage;
    
            for (const auto& name : filenames)
            {
                currentImage = cv::imread(name);
                cv::add(S, currentImage, S, cv::noArray(), CV_64F);
            }
            S /= filenames.size();
    
            cv::Mat3b avg;
            S.convertTo(avg, CV_8U);
    
            double toc = double(cv::getTickCount());
    
            double timeLoad = (toc - ticLoad) / cv::getTickFrequency();
            double time = (toc - tic) / cv::getTickFrequency();
            std::cout << "@Miki: " << time << " s (" << timeLoad << " s)" << std::endl;
        }
        getchar();
    
    
    
    
    
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    int main()
    {
    double ticLoad=double(cv::getTickCount());
    std::string folder=“D:\\SO\\temp\\old\u 075\u 6\\\*.bmp”;
    std::矢量文件名;
    cv::glob(文件夹、文件名);
    int行,cols;
    {
    //只需加载第一个图像即可获得行和列
    cv::Mat3b img=cv::imread(文件名[0]);
    行=img.rows;
    cols=img.cols;
    }
    /*{
    double tic=double(cv::getTickCount());
    cv::Mat3d S(行,列,0.0);
    for(const auto&名称:文件名)
    {
    cv::Mat currentImage=cv::imread(名称);
    currentImage.convertTo(currentImage,CV_64F);
    S+=当前图像;
    }
    S=S*double(1.0/filenames.size());
    cv::Mat3b平均值;
    S.convertTo(平均值,CV_8U);
    double-toc=double(cv::getTickCount());
    double timeLoad=(toc-ticLoad)/cv::getTickFrequency();
    双时间=(toc-tic)/cv::getTickFrequency();
    
    std::cout您的代码似乎足够好,在我的测试中,我发现它的运行速度比Matlab代码快10倍

    然而,我展示了一个稍微优化的代码,它的执行速度比您的稍快

    注释

    请注意,我没有一个文件夹,名为“你”,所以我在C++版本中使用了<代码> CV::GOLB,在Matlab版本中使用<代码> dir < /Cord>获取文件夹中图像的名称。 在我的文件夹中,我有82个小图像,因此运行时间明显比您的小,但相对性能应该是可靠的

    执行时间

                        Sum only      Get filenames + Sum
    Matlab:             0.173543 s    (0.185308 s)
    OpenCV @Seven Wang: 0.0145206 s   (0.0155748 s)
    OpenCV @Miki:       0.0128943 s   (0.013333 s)
    
    注意事项

    确保在OpenCV和Matlab中一致地计算运行时间


    代码

                        Sum only      Get filenames + Sum
    Matlab:             0.173543 s    (0.185308 s)
    OpenCV @Seven Wang: 0.0145206 s   (0.0155748 s)
    OpenCV @Miki:       0.0128943 s   (0.013333 s)
    
    Matlab代码:

    tic
    
    folder = 'D:\\SO\\temp\\old_075_6\\';
    filenames = dir([folder '*.bmp']);
    
    % Get rows and cols from 1st image
    img = imread([folder name]);
    
    
    
    S = zeros(size(img));
    
    for ii = 1 : length(filenames)
        name = filenames(ii).name;
        currentImage = imread([folder name]);    
        S = S + double(currentImage);
    end
    
    S = uint8(round(S / length(filenames)));
    
    toc
    
    C++代码:

    #include <opencv2\opencv.hpp>
    #include <vector>
    #include <iostream>
    
    int main()
    {
        double ticLoad = double(cv::getTickCount());
    
        std::string folder = "D:\\SO\\temp\\old_075_6\\*.bmp";
        std::vector<cv::String> filenames;
        cv::glob(folder, filenames);
    
        int rows, cols;
        {
            // Just load the first image to get rows and cols
            cv::Mat3b img = cv::imread(filenames[0]);
            rows = img.rows;
            cols = img.cols;
        }
    
        /*{
            double tic = double(cv::getTickCount());
    
            cv::Mat3d S(rows, cols, 0.0);
    
            for (const auto& name : filenames)
            {
                cv::Mat currentImage = cv::imread(name);
                currentImage.convertTo(currentImage, CV_64F);
    
                S += currentImage;
    
            }
            S = S * double(1.0 / filenames.size());
    
            cv::Mat3b avg;
            S.convertTo(avg, CV_8U);
    
            double toc = double(cv::getTickCount());
    
            double timeLoad = (toc - ticLoad) / cv::getTickFrequency();
            double time = (toc - tic) / cv::getTickFrequency();
            std::cout << "@Seven Wang: " << time << " s (" << timeLoad << " s)" << std::endl;
        }*/
    
        {
            double tic = double(cv::getTickCount());
    
            cv::Mat3d S(rows, cols, 0.0);
            cv::Mat3b currentImage;
    
            for (const auto& name : filenames)
            {
                currentImage = cv::imread(name);
                cv::add(S, currentImage, S, cv::noArray(), CV_64F);
            }
            S /= filenames.size();
    
            cv::Mat3b avg;
            S.convertTo(avg, CV_8U);
    
            double toc = double(cv::getTickCount());
    
            double timeLoad = (toc - ticLoad) / cv::getTickFrequency();
            double time = (toc - tic) / cv::getTickFrequency();
            std::cout << "@Miki: " << time << " s (" << timeLoad << " s)" << std::endl;
        }
        getchar();
    
    
    
    
    
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    int main()
    {
    double ticLoad=double(cv::getTickCount());
    std::string folder=“D:\\SO\\temp\\old\u 075\u 6\\\*.bmp”;
    std::矢量文件名;
    cv::glob(文件夹、文件名);
    int行,cols;
    {
    //只需加载第一个图像即可获得行和列
    cv::Mat3b img=cv::imread(文件名[0]);
    行=img.rows;
    cols=img.cols;
    }
    /*{
    double tic=double(cv::getTickCount());
    cv::Mat3d S(行,列,0.0);
    for(const auto&名称:文件名)
    {
    cv::Mat currentImage=cv::imread(名称);
    currentImage.convertTo(currentImage,CV_64F);
    S+=当前图像;
    }
    S=S*double(1.0/filenames.size());
    cv::Mat3b平均值;
    S.convertTo(平均值,CV_8U);
    double-toc=double(cv::getTickCount());
    double timeLoad=(toc-ticLoad)/cv::getTickFrequency();
    双时间=(toc-tic)/cv::getTickFrequency();
    性病