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();
性病