0

I have a 16 bit grayscale camera stream with 30fps (1024x768px) and want to write each image as fast as possible to hard disk. The images sould not be compressed with lossy methods, I need every bit for further processing.

I tried it with but unfortunately PNG and TIFF are to slow and BMP does not support 16 bit in openCV.

Do you have an idea how to achieve this? Below there is a sample for writing and reading PNG in OpenCV. Changeing compression level of PNG is not enough. Reading images from camera is still faster than writing. I also tried using multiple threads with boost thread pool, but without success.

Thank you

#include <iostream>
#include <opencv2/imgcodecs.hpp>

int main(int argc, char *argv[])
{
    cv::Mat imOut = cv::Mat::ones(cv::Size(1024, 768), CV_16UC1);
    cv::imwrite("test.png", imOut); 
    return 0;
}

Edit:

System:

  • Windows 10 64 bit
  • MSVC c++ compiler
  • CPU Intel i7
  • 16 GB RAM (but it should be done with less)
  • Disk subsystem: best would be direct write on external USB 3 hard disk, but possible internal hard disk is also ok. Unfortunately SSD is not available
  • How long do you need to acquire for? What OS do you use? What CPU? What do your disk subsystems look like? How much RAM do you have? – Mark Setchell Nov 03 '20 at 08:36
  • edited my post with system properties. – Daniel Andres Nov 03 '20 at 08:57
  • @Alex F: If possible I would avoid the two-step solution. this wwould be my fallback solution. thanks – Daniel Andres Nov 03 '20 at 08:57
  • check [this](https://stackoverflow.com/a/32357875/5008845). You can save the images with matwrite, and then load them back with matread directly in a cv::Mat. – Miki Nov 03 '20 at 10:06
  • @Miki thanks. I found another way with a standardized image format. – Daniel Andres Nov 03 '20 at 10:50
  • Not sure about your comment that *"BMP doesn't support 16-bit in **OpenCV**"*. I don't believe BMP supports 16-bit per pixel greyscale at all, anywhere, full stop. – Mark Setchell Nov 03 '20 at 12:04
  • AFAIK, all Intel Core i7 processors have at least 4 cores, so assuming you have 1 core reading the video, you should have 3 or more cores available for writing. If you want to achieve 30 fps, that means each core needs to achieve 10fps or 100ms per image. That sounds quite achievable. Did you try with representative video data - your sample code is not very representative. Did you benchmark the actual performance? – Mark Setchell Nov 03 '20 at 12:34
  • @MarkSetchell maybe I had a misunderstanding of BMP capabilities. with PGM format this works without any problem. – Daniel Andres Nov 03 '20 at 13:47
  • @MarkSetchell I had used a boost thread pool and io context to manage the save parts. but maybe my implementation was not utlizing the cores correctly. – Daniel Andres Nov 03 '20 at 13:48

1 Answers1

0

I found an answer, which was not documented.

The PGM Format support 16-bit grayscale with fast writing.

cv::imwrite("test.pgm", imOut); 

I opened an issue to update OpenCV documentation. OpenCV 4.5.0 imwrite Documentation OpenCV Issue

Thank you.