C++ 除了使用OpenCV',还有其他选择吗;什么是解码?太慢了

C++ 除了使用OpenCV',还有其他选择吗;什么是解码?太慢了,c++,image,opencv,memory-management,C++,Image,Opencv,Memory Management,我创建了一个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

我创建了一个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);
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;
}
第一个
readImage(filePath)
是使用速度相当快的
cv::imread(filePath)
实现的(对于600 x 900的图像,平均0.001秒)。但是,第二个版本
readImage(fileStream)
是使用
cv::imdecode
实现的,它的速度相当慢(对于相同的图像,平均2.5秒)

除了
cv::imdecode
之外,我还可以从内存缓冲区解码图像,而不用花这么长时间吗?这是一个经常使用的应用程序的核心组件,所以它必须是快速的

任何协助都将不胜感激。提前谢谢

编辑:

我用计时器测量计时。这对我来说也没什么意义。我不明白为什么时间上有这么大的差距
Image2D
只是一个以OpenCV矩阵为成员的类。
readImage
功能的实现简化如下:

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);
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;
}
int-Image2D::readImage(std::ifstream&input)
{       
input.seekg(0,std::ios::end);
size_t fileSize=input.tellg();
input.seekg(0,std::ios::beg);
如果(文件大小==0){
返回1;
}
std::矢量数据(文件大小);
input.read(重新解释强制转换(&data[0]),sizeof(无符号字符)*fileSize;
如果(!输入){
返回1;
}
秒表;
mImg=cv::imdecode(cv::Mat(数据),cv\u LOAD\u IMAGE\u COLOR);

std::cout这就是我测试代码的方式,也许您可以尝试同样的方法(在一个干净的项目中)来比较结果

对我来说,时间测量(CPU时间,不是墙时间)表明,仅仅解码字节流比读取图像(这是有意义的)要快一点-Windows-VC 2010 OpenCV 2.49

#include <fstream>

cv::Mat MreadImage(std::ifstream& input)
{       
    input.seekg(0, std::ios::end);
    size_t fileSize = input.tellg();
    input.seekg(0, std::ios::beg);

    if (fileSize == 0) {
        return cv::Mat();
    }

    std::vector<unsigned char> data(fileSize);
    input.read(reinterpret_cast<char*>(&data[0]), sizeof(unsigned char) * fileSize);

    if (!input) {
        return cv::Mat();
    }

    clock_t startTime = clock();
    cv::Mat mImg = cv::imdecode(cv::Mat(data), CV_LOAD_IMAGE_COLOR);
    clock_t endTime = clock();
    std::cout << "Time to decode image: " << (float)(endTime-startTime)/(float)CLOCKS_PER_SEC << std::endl;

    return mImg;
}


cv::Mat MreadImage(const std::string& fileName)
{
    clock_t startTime = clock();
    cv::Mat mImg = cv::imread(fileName, CV_LOAD_IMAGE_COLOR);
    clock_t endTime = clock();

    std::cout << "Time to read image: " << (float)(endTime-startTime)/(float)CLOCKS_PER_SEC << std::endl;
    return mImg;
}

// test speed of imread vs imdecode
int main()
{

    //std::string path = "../inputData/Lenna.png";
    //std::string path = "../inputData/Aachen_Germany_Imperial-Cathedral-01.jpg";
    std::string path = "../inputData/bmp.bmp";

    cv::Mat i1 = MreadImage(path);


    std::ifstream imgStream (path.c_str(), std::ios::binary);
    cv::Mat i2 = MreadImage(imgStream);

    cv::imshow("input 1", i1);
    cv::imshow("input 2", i2);
    cv::waitKey(0);
    return 0;
}
#包括
cv::Mat MreadImage(std::ifstream和input)
{       
input.seekg(0,std::ios::end);
size_t fileSize=input.tellg();
input.seekg(0,std::ios::beg);
如果(文件大小==0){
返回cv::Mat();
}
std::矢量数据(文件大小);
input.read(重新解释强制转换(&data[0]),sizeof(无符号字符)*fileSize;
如果(!输入){
返回cv::Mat();
}
时钟开始时间=时钟();
cv::Mat mImg=cv::imdecode(cv::Mat(数据),cv\U LOAD\U IMAGE\U COLOR);
clock_t endTime=clock();

std::cout您如何测量计时?这似乎没有多大意义:
imread
在内部使用
imdecode
,而您只是读取一个实际上根本没有解码的位图文件。您还应该显示类
Image2D
的代码和方法
readImage
的实现(2个重载选项)。请参阅我的编辑@Antonio。秒表是如何实现的?因为您第一次测量imread,可能是某种单态,而不是重置的?使用时钟测量(我知道是cpu时间,不是墙壁时间),流版本稍微快一点(但只是解码)在我的系统上。@Mika不,它绝对不是一个单例。只是一个使用Windows的简单轻量级类。我不明白流版本在你的机器上如何更快,但在我的机器上却慢得多。事实上,在我测试过的几台机器上,它更慢。所以我在一个干净的项目中测试了上面的代码,时间大约是和你提到的一样。我真的不明白为什么在我的生产级应用程序中运行
imdecode
需要更长的时间。我必须更深入地研究这个问题。我可能遗漏了一些东西。任何建议都会有所帮助。谢谢。你在生产代码中尝试过替代时间测量方法吗?是的,我尝试过。我不知道理解为什么需要这么长时间。我为这个问题创建了一个解决方案,但我仍然对时间上的差异感到困惑。我不知道为什么我显式地调用
cv::imdecode
,需要更长的时间。谢谢你的帮助。