【发布时间】:2015-05-07 20:48:36
【问题描述】:
我创建了一个 DLL,用户可以在其中从文件名或流中读取图像,如下所示:
std::string filePath = "SomeImage.bmp";
// (1) Reading from a file
Image2D img1;
img1.readImage(filePath);
// (2) Reading from a stream
std::ifstream imgStream (filePath.c_str(), std::ios::binary);
Image2D img2;
img2.readImage(imgStream);
第一个readImage(filePath) 是使用cv::imread(filePath) 实现的,速度相当快(对于600 x 900 的图像,平均需要0.001 秒)。然而,第二个版本readImage(fileStream) 是使用cv::imdecode 实现的,这相当慢(对于相同的图像平均需要2.5 秒)。
是否有任何替代 cv::imdecode 的方法,我可以从内存缓冲区中解码图像而无需花费这么长时间?这是针对经常使用的应用程序的核心组件,所以它必须快速。
我们将不胜感激。提前致谢。
编辑:
我使用计时器测量时间。这对我来说也没有意义。我不明白为什么在时间上有这么大的差距。 Image2D 只是一个以 OpenCV 矩阵为成员的类。 readImage函数的实现简化如下:
int Image2D::readImage(std::ifstream& input)
{
input.seekg(0, std::ios::end);
size_t fileSize = input.tellg();
input.seekg(0, std::ios::beg);
if (fileSize == 0) {
return 1;
}
std::vector<unsigned char> data(fileSize);
input.read(reinterpret_cast<char*>(&data[0]), sizeof(unsigned char) * fileSize);
if (!input) {
return 1;
}
StopWatch stopWatch;
mImg = cv::imdecode(cv::Mat(data), CV_LOAD_IMAGE_COLOR);
std::cout << "Time to decode: " << stopWatch.getElapsedTime() << std::endl;
return 0;
}
int Image2D::readImage(const std::string& fileName)
{
StopWatch stopWatch;
mImg = cv::imread(fileName, CV_LOAD_IMAGE_COLOR);
std::cout << "Time to read image: " << stopWatch.getElapsedTime() << std::endl;
return 0;
}
【问题讨论】:
-
你如何衡量时间?这似乎没有多大意义:
imread在内部使用imdecode,而您只是在读取实际上根本没有解码的位图文件。您还应该显示您的类Image2D和方法readImage实现的代码(2 个重载选项)。 -
查看我的编辑@Antonio。
-
秒表是如何实现的?自从您第一次测量 imread 以来,也许它是某种单例且未重置?
-
用时钟测量(我知道这是 cpu 时间,而不是 wall 时间),流版本在我的系统上要快一些(但它只是解码)。
-
@Micka 不,这绝对不是单例。只是一个使用 Windows _ftime64_s 的简单轻量级类。我不明白流版本在您的机器上如何更快,但在我的机器上却慢得多。事实上,在我测试过的几台机器上,它的速度更慢。
标签: c++ image opencv memory-management