2015-05-07 11 views
5

tôi đã tạo ra một DLL nơi người dùng có thể hoặc là đọc một hình ảnh từ một tên tập tin hoặc từ một dòng như sau:Có cách nào khác để sử dụng mã imdecode của OpenCV không? Đó là quá chậm

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); 

Đầu tiên readImage(filePath) được thực hiện sử dụng cv::imread(filePath) đó là hợp lý nhanh (trên trung bình 0,001 giây cho hình ảnh 600 x 900). Tuy nhiên, phiên bản thứ hai readImage(fileStream) được triển khai bằng cách sử dụng cv::imdecodechậm hơn đáng kể (trung bình 2,5 giây cho cùng một hình ảnh).

Có lựa chọn thay thế nào cho cv::imdecode nơi tôi có thể giải mã hình ảnh từ bộ nhớ đệm mà không mất một thời gian dài như vậy không? Điều này là dành cho thành phần cốt lõi của một ứng dụng thường được sử dụng, vì vậy nó phải nhanh chóng.

Mọi hỗ trợ sẽ được đánh giá cao. Cảm ơn trước.

EDIT:

Tôi đo thời gian bằng bộ hẹn giờ. Nó không có ý nghĩa với tôi nữa. Tôi không hiểu tại sao có một sự chênh lệch lớn như vậy trong thời gian đó. Image2D chỉ là một lớp có ma trận OpenCV làm thành viên. Việc thực hiện các chức năng readImage được đơn giản hóa như sau:

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; 
} 
+2

Bạn đo thời gian như thế nào? Điều này dường như không có ý nghĩa nhiều: 'imread' sử dụng' imdecode' trong nội bộ, và bạn chỉ đọc một tệp bitmap mà thực sự không có giải mã chút nào. Bạn cũng nên hiển thị mã cho lớp của bạn 'Image2D' và phương thức' readImage' implementation (2 tùy chọn bị quá tải). – Antonio

+0

Xem các chỉnh sửa của tôi @Antonio. – Duncs

+0

đồng hồ bấm giờ đó được triển khai như thế nào? kể từ khi bạn đầu tiên đo lường imread, có thể một số loại singleton của nó và không tái định cư? – Micka

Trả lời

2

Đây là cách tôi kiểm tra mã của bạn, có lẽ bạn có thể thử như nhau (trong một dự án sạch) để so sánh kết quả.

Đối với tôi, thời gian đo lường (thời gian CPU, nó không tường thời gian) cho biết đó là một chút nhanh hơn để chỉ giải mã các dòng byte hơn để imread hình ảnh (có ý nghĩa) - 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; 
} 
+0

Vì vậy, tôi đã thử nghiệm mã ở trên trong một dự án sạch sẽ và thời gian là về giống như bạn đã đề cập. Tôi thực sự không hiểu tại sao nó mất nhiều thời gian hơn để chỉ chạy 'imdecode' trong ứng dụng mức sản xuất của tôi. Tôi sẽ phải thâm nhập sâu hơn một chút. Tôi có thể thiếu một cái gì đó. Mọi lời khuyên sẽ giúp ích. Cảm ơn. – Duncs

+0

bạn đã thử phương pháp đo thời gian thay thế trong mã sản xuất của mình chưa? – Micka

+1

Vâng, tôi đã làm. Tôi không hiểu tại sao phải mất quá lâu. Tôi tạo ra một công việc xung quanh cho vấn đề này nhưng tôi vẫn hoang mang bởi sự khác biệt về thời gian. Tôi không có đầu mối tại sao phải mất một thời gian lâu hơn khi tôi gọi một cách rõ ràng 'cv :: imdecode'. Cám ơn sự giúp đở cuả bạn. – Duncs

Các vấn đề liên quan