5

I am using a Basler camera and want to write images that I grabbed at 1000x1000px to disk as fast as possible. Keeping a movie container open and saving as .avi doesn't really help (slows down 2x) and saving single images is even slower. I am currently using openCV cvVideoCreator and imwrite functions. My computer should be fast enough (Intel Xeon 3.6 GHz, 64GB RAM, SSD). Any ideas?

Horst
  • 167
  • 1
  • 6
  • What's the typical size of a uncompressed and compressed image (and how long does the compression take)? What frame rate are you using? What is the sustainable transfer-rate of your hard disc? Do the above numbers make sense? – Richard Critten Nov 27 '17 at 14:21
  • What is a "cvVideoCreator"? A quick search nets no useful results. – Dan Mašek Nov 27 '17 at 14:30
  • Any requirements on how the data is represented? Colour or monochrome? I assume compression (if any) should be lossless? – Dan Mašek Nov 27 '17 at 14:39
  • 1
    What is fast for you? 200 frames per second? 30 ? 5? also, what is your current speed? 1000 x 1000 pixels is not a huge image, and with such a pc configuration you should achieve a fast speed with imwrite... and it comes again to the question, what is fast for you? – api55 Nov 27 '17 at 14:39
  • In case of a colour camera, it's a good bet that you can capture raw (Bayer) images (before demoisacing is done). Those are single channel, so you cut the amount of data to 1/3 if you store them in that state. | Of course, capture and storage running in separate threads is kinda given. – Dan Mašek Nov 27 '17 at 14:48
  • You can save the mat in binary format. That's pretty fast. Have a look [here](https://stackoverflow.com/a/32357875/5008845) – Miki Nov 27 '17 at 18:19
  • The image is RGB and I want to write it at 50 fps. I write out as JPG and each file has a size of about 492 KB. I am writing to SSD. If I use imwrite, framerates slow down to about 10 fps, if I use a VideoWriter object and write to that container, it slows down to about 30 fps. I had a quick look at writing mat in binary format (thanks @Miki), but couldn't figure out how to append to the binary file continously while acquiring images. Any other ideas? If I resize images with opencv resize or pyrDown (to let's say 500x500 px) I also loose time and things slow down. – Horst Nov 29 '17 at 09:36
  • Why you want to append continuously? Save each image as you would do with imwrite – Miki Nov 29 '17 at 09:56
  • Yes, that was stupid. Thanks, it actually works quite nicely. I can write out the images at around 48fps. The problem now is that, since there is no jpg compression or whatever, the color 1500x1500px images are 6.43 MB in size. That is too much data for the recording length that I want. Any ideas how to deal with that? – Horst Nov 29 '17 at 12:20

2 Answers2

8

There are multiple factors (steps) you may want to consider in order to reach your goal (saving color images (1K x 1K x 3) with 50 FPS or 150 MB/s).

  1. Image encoding: most of well-known image formats such as png, tif, jpg takes time to encode image (e.g., 5.7 ms for png and 11.5 ms for tif in OpenCV with 3.6 GHz 4-core CPU) to the specific format even before saving the encoded format data to a disk.

  2. File opening: Independent of file size, this may take time (e.g., 1.5 ms on 3.5" WD Black)

  3. File writing: Dependent of file size, this may take time (e.g., 2.0 ms on 3.5" WD Black)

  4. File closing: Dependent of file size, this may take a lot of time (e.g., 14.0 ms on 3.5" WD Black)

This means you have to finish all of the steps in 20 ms per image for your goal, and as I gave examples of timing, you may not be able to achieve your goal with OpenCV imwrite in JPG because the library sequentially does all the steps above in a single thread.

I think you have a couple of options

  1. imwrite into BMP format on SSD as its encoding time is virtually zero (e.g., less than 0.3 ms)

  2. do some of steps above (e.g., encoding or file closing) in a separate thread.

Especially, file closing is a good candidate to be run in a separate thread because it can be asynchronously done with the other steps. I was able to reach 400 MB/s bandwidth of saving with the second option, BMP file format, and a better hard disk.

Hope this helps you and others with similar goals.

Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240
0

The specs you state in your question are related to your ability to process and buffer the data, but not about the speed you can dump to disk.

You're trying to write (some numbers assumed, just replace with your own) 1000*1000 (size) * 4 (data/pixel) * 25 (frame rate) bytes per second.
(or 100M/s)

This is around abouts the limit of a traditional HDD, but if the disk is fragmented or full at all it's unlikely to keep up. As a result you must find a way to either speed up your write time (switch to SSD for example); reduce the data being written (compress, reduction in colour depth / quality / frame rate) or buffer what you want to write while a background thread saves to disk.

The question you must ask is how long do you plan to record for. If it's not long enough to fill up your RAM, then you have all the options available to you. If however you plan to record for extended periods of time then you will have to pick one of the other 2.

UKMonkey
  • 6,941
  • 3
  • 21
  • 30
  • Probably 3 bytes per pixel, not like transparency is relevant for images coming from a camera. – Dan Mašek Nov 27 '17 at 14:46
  • @DanMašek I'd like to say that this would make the difference, but I've seen hard disks struggle with 10M/s writes ... And I did say that values were assumed. – UKMonkey Nov 27 '17 at 14:48