# SaveLossyImage and threading

**URL:** <https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471>\
**Category:** Programming Questions\
**Tags:** csharp, acquisition\
**Created:** [June 13, 2018, 3:10pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471 "2018-06-13T15:10:40Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 13, 2018, 3:10pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/1 "2018-06-13T15:10:40Z")

</div>

In an attempt to speed up a recording application that uses SaveLossyImage, I use a task to do the saving. However, this does not have the expected result, still I cannot get to the same speeds as when saving .bmps. Am I overlooking something? Is there some way to get the AxCVImage object to offload the compression to another thread, so as not to block the main image processing.

Any suggestions?

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [June 13, 2018, 3:43pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/2 "2018-06-13T15:43:01Z")

</div>

Unfortunately thread-safety of the serialization of image files cannot be guaranteed as this is not something that not all of the underlying libraries offer. For example jpeg relies on the [libjpg](https://de.wikipedia.org/wiki/Libjpeg) which is expressly not thread safe. Is lossy compression a requirement (e.g. due to disc space limitations)? Because if it isn’t: By and large the fastest way to store :cvb: images to files is the \*.bmp format…

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 14, 2018, 6:59am UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/3 "2018-06-14T06:59:02Z")

</div>

I had indeed noticed that the storing of .bmp images is orders of magnitude faster. But yeah, the required storage capacity quickly gets out of hand with .bmps.

---

<div class="post-metadata">

**Author:** ![rtp\_derahs](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/rtp_derahs/32/79_2.png) [@rtp\_derahs](https://forum.commonvisionblox.com/u/rtp_derahs)\
**Post date:** [June 14, 2018, 12:14pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/4 "2018-06-14T12:14:38Z")

</div>

An alternative would be to save the images to an .avi-file using H.264 compression with Movie2 from :cvb:.  
If this is an option for you, have a look at the Movie2 Example at %CVB%Tutorial\Movie2  
A licence for this encoder can be ordered from Stemmer Imaging.  
Encoding the video can also be speeded up with hardware acceleration (Intel Quicksync / Nvidia Cuda) and by adjusting the quality factor of the encoder (1 - 50, where 1 is the best quality). We tested the compression of H.264 with 8Bit images and archived following compression rates:

- Quality factor 10: 10:1
- Quality factor 16: 50:1
- Quality factor 22: 200:1

At which resolution/framerate are you recording?

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 14, 2018, 12:16pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/5 "2018-06-14T12:16:59Z")

</div>

7600\*3500, 2 herz per camera, 2 cameras. SaveLossyImage takes somewhere around 500-600(!!) ms per image.

---

<div class="post-metadata">

**Author:** ![rtp\_derahs](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/rtp_derahs/32/79_2.png) [@rtp\_derahs](https://forum.commonvisionblox.com/u/rtp_derahs)\
**Post date:** [June 14, 2018, 12:27pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/6 "2018-06-14T12:27:29Z")

</div>

Alright since H.264 only supports 4096x4096 MAX, the only alternative is H.265.  
We haven’t tested that yet, but according to the manufacturer, H.265 supports videos up to 8K resolution.

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 14, 2018, 2:35pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/7 "2018-06-14T14:35:15Z")

</div>

Hmm, It seems that it’s not actually the compression that is the culprit. Using the bitmap.save function from windows, saving images of that size takes about 100ms. Odd!

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 15, 2018, 11:48am UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/8 "2018-06-15T11:48:31Z")

</div>

Ok, so using the tutorial sample c# CSIMG2Bitmap, and calling the standard windows codec it’s possible to get this to run in multiple threads. The suprising thing is that it wasn’t actually the jpeg encoding that was the problem for these big images, the conversion from cvImage to Bmp was the bottleneck.

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [June 16, 2018, 10:30pm UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/9 "2018-06-16T22:30:35Z")

</div>

Hi @CvK,

we’d have to have a detailed look, but what you write seems consistent with the measurements I’ve done for [this](https://forum.commonvisionblox.com/t/different-performance-when-saving-different-formats/252/4) post. With your roughly 26 MPixel images I’d expect roughly 200 ms on my machine for saving these (haven’t tested so far), which is somewhat more than the 100ms you’re measuring.

Saving bitmap files internally uses C++'s `std::fstream` for input/output. On VC these are unfortunaly slower than the C methods `fopen` and its cousins (interestingly, this doesn’t seem to be the case for the gcc) which is probably your limiting factor for BMP writing - at least in those scenarios where the memory layout allows for direct streaming. As soon as the memory has to be reordered, reordering becomes the bottleneck.

If copying from the :cvb: image to the `System.Drawing.Bitmap` now is your bottleneck there is in fact a way for your code to become faster: Even in the case of linear VPATs the CSIMG2Bitmap tutorial copies pixel by pixel. However, there are scenarios where you can get a lot faster by copying entire lines or even the whole block of pixels (basically the x increment has to equal the pixel’s size and the y increment has to equal the target bitmap’s stride for this to be possible - so you’ll need to check the return values of `GetLinearAccess` for compliance with these requirements). Copying blocks of unmanaged memory in C# requires some additional [`DllImport` magic](https://stackoverflow.com/questions/15975972/copy-data-from-from-intptr-to-intptr) but it’s feasible and I’d expect the copying of the pixel data to become faster faster by a factor of somewhere between 2 and 3 if you can at least do it line by line.

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 18, 2018, 6:54am UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/10 "2018-06-18T06:54:41Z")

</div>

Handing off the conversion to different tasks was good enough for the current application. I always get this sense of foreboding dread whenever I read the words “Copying blocks of unmanaged memory in c#”. Anyhow, it works now, and thanks for providing the extra elaboration / extra credit approach.

With the threading approach I managed to get about 3 fps for 2 rgb cameras, so not too shabby I’d say! If later it turns out that we need a performance boost I’ll venture into the lands of unmanaged memory copying. If I’m not back in three days… send rescue parties 😉

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [June 18, 2018, 8:32am UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/11 "2018-06-18T08:32:57Z")

</div>

😱  
We’re talking RGB here? Bloody h…, so you’re streaming about 450 MB/s to jpg? No worries, we’ll send Chuck Norris for you 👍

---

<div class="post-metadata">

**Author:** ![CvK](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/cvk/32/112_2.png) [@CvK](https://forum.commonvisionblox.com/u/CvK)\
**Post date:** [June 18, 2018, 8:38am UTC](https://forum.commonvisionblox.com/t/savelossyimage-and-threading/471/12 "2018-06-18T08:38:14Z")

</div>

Hmm, looking back on the formulation of my question. I perhaps should’ve mentioned the _“detail”_ about it being RGB.
