简体   繁体   English

OpenCV vs字节数组

[英]OpenCV vs byte array

I am working on a simple C++ image processing application and deciding whether to use OpenCV for loading the image and accessing individual pixels. 我正在研究一个简单的C ++图像处理应用程序,并决定是否使用OpenCV加载图像和访问单个像素。 My current approach is to simply load the image using fopen , reading the 54 byte header and load the rest of the bytes in a char* array. 我目前的方法是简单地使用fopen加载图像,读取54字节的头并在char*数组中加载其余的字节。

To access a specific pixel I use 要访问我使用的特定像素

long q = (long*)(bmpData + x*3 + (bmpSize.height - y - 1) * bmpSize.stride);

To perform a simple color check, for ex. 要进行简单的颜色检查,例如 "is blue?" “是蓝色的吗?”

if (((long*)q | 0xFF000000) == 0xFFFF0000) //for some reason RGB is reversed to BGR
  //do something here

Is OpenCV any faster considering all the function calls, parsing, etc.? 考虑到所有函数调用,解析等,OpenCV会更快吗?

Bitmap file header is actually 54 bytes and you can't skip it. 位图文件头实际上是54个字节,你不能跳过它。 You have to read it to find the width, height, bitcount... calculate padding if necessary... and other information. 你必须阅读它才能找到宽度,高度,bitcount ...如有必要,可以计算填充......以及其他信息。

Depending on how the file is opened, OpenCV will read the header and reads the pixels directly in to a buffer. 根据文件的打开方式,OpenCV将读取标头并将像素直接读入缓冲区。 The only change is that the rows are flipped so the image is right side up. 唯一的变化是行被翻转,因此图像正面朝上。

cv::Mat mat = cv::imread("filename.bmp", CV_LOAD_IMAGE_COLOR);
uint8_t* data = (uint8_t*)mat.data;

The header checks and the small changes made by OpenCV will not significantly affect performance. 标头检查和OpenCV所做的小改动不会显着影响性能。 The bottle neck is mainly in reading the file from the disk. 瓶颈主要是从磁盘读取文件。 The change in performance will be difficult to measure, unless you are doing a very specific task, for example you want only 3 bytes in a very large file, and you don't want to read the entire file. 除非您正在执行非常特定的任务,否则性能的变化将难以衡量,例如,您只想在非常大的文件中使用3个字节,并且您不想读取整个文件。

OpenCV is overkill for this task, so you may choose other libraries for example CImg as suggested in comments. OpenCV对于此任务来说太过分了,因此您可以按照注释中的建议选择其他库,例如CImg。 If you use smaller libraries they load faster, it might be noticeable when your program starts. 如果你使用较小的库,它们加载速度更快,程序启动时可能会很明显。


The following code is a test run on Windows. 以下代码是在Windows上运行的测试。

For a large 16MB bitmap file, the result is almost identical for opencv versus plain c++. 对于大型16MB位图文件,opencv与普通c ++的结果几乎相同。

For a small 200kb bitmap file, the result is 0.00013 seconds to read in plain C++, and 0.00040 seconds for opencv. 对于一个小的200kb位图文件,在纯C ++中读取的结果为0.00013秒,对于opencv则为0.00040秒。 Note the plain c++ is not doing much beside reading the bytes. 请注意,除了读取字节之外,普通c ++没有做太多工作。

 class stopwatch { std::chrono::time_point<std::chrono::system_clock> time_start, time_end; public: stopwatch() { reset();} void reset(){ time_start = std::chrono::system_clock::now(); } void print(const char* title) { time_end = std::chrono::system_clock::now(); std::chrono::duration<double> diff = time_end - time_start; if(title) std::cout << title; std::cout << diff.count() << "\\n"; } }; int main() { const char* filename = "filename.bmp"; //I use `fake` to prevent the compiler from over-optimization //and skipping the whole loop. But it may not be necessary here int fake = 0; //open the file 100 times int count = 100; stopwatch sw; for(int i = 0; i < count; i++) { //plain c++ std::ifstream fin(filename, std::ios::binary); fin.seekg(0, std::ios::end); int filesize = (int)fin.tellg(); fin.seekg(0, std::ios::beg); std::vector<uint8_t> pixels(filesize - 54); BITMAPFILEHEADER hd; BITMAPINFOHEADER bi; fin.read((char*)&hd, sizeof(hd)); fin.read((char*)&bi, sizeof(bi)); fin.read((char*)pixels.data(), pixels.size()); fake += pixels[i]; } sw.print("time fstream: "); sw.reset(); for(int i = 0; i < count; i++) { //opencv: cv::Mat mat = cv::imread(filename, CV_LOAD_IMAGE_COLOR); uint8_t* pixels = (uint8_t*)mat.data; fake += pixels[i]; } sw.print("time opencv: "); printf("show some fake calculation: %d\\n", fake); return 0; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM