有没有其他方法可以使用OpenCV的imdecode?它太慢

时间:2015-05-07 20:48:36

标签: 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.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;
}

1 个答案:

答案 0 :(得分:2)

这是我测试你的代码的方法,也许你可以尝试相同的(在一个干净的项目中)来比较结果。

对我来说,时间测量(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;
}