# Imshow() and imwrite() outputs are different and normalization is not preserving original image

**URL:** <https://forum.opencv.org/t/imshow-and-imwrite-outputs-are-different-and-normalization-is-not-preserving-original-image/2925>\
**Category:** Python\
**Tags:** highgui, imgcodecs\
**Created:** [April 22, 2021, 6:08pm UTC](https://forum.opencv.org/t/imshow-and-imwrite-outputs-are-different-and-normalization-is-not-preserving-original-image/2925 "2021-04-22T18:08:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dasyud](https://avatars.discourse-cdn.com/v4/letter/d/0ea827/32.png) [@Dasyud](https://forum.opencv.org/u/Dasyud)\
**Post date:** [April 22, 2021, 6:08pm UTC](https://forum.opencv.org/t/imshow-and-imwrite-outputs-are-different-and-normalization-is-not-preserving-original-image/2925/1 "2021-04-22T18:08:18Z")

</div>

I’m using the CUDA functions to calculate optical flow. I want to save the images to disk but the original array has float values ranging around -5 to 5, which gives black images when using imwrite.

Normalization to 0-255 is changing the output, although it manages to give the same output for imshow and imwrite.

Is it possible to write the image I originally viewed through imshow (the float array)?

Thanks.

Code:

```
#FLOW COMPUTATION
gpu_flow = brox_of.calc(gpu_prev, gpu_frame, None) #2 vectors

#splitting flow into 2
gpu_flow_x = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
gpu_flow_y = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
temp = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_8U)
cv2.cuda.split(gpu_flow, [gpu_flow_x, gpu_flow_y], cv2.cuda.Stream_Null())

# set value to normalized magnitude from 0 to 255
#gpu_flow_x = cv2.cuda.normalize(gpu_flow_x, 0, 1, cv2.NORM_MINMAX, -1)
#print(gpu_flow_x.type())
#gpu_flow_y = cv2.cuda.normalize(gpu_flow_y, 0, 255, cv2.NORM_MINMAX, -1)

#help(cv2.cuda_GpuMat.convertTo)
gpu_flow_x.convertTo(cv2.CV_8U, temp)
x = gpu_flow_x.download()
y = gpu_flow_y.download()
#x3d = np.expand_dims(x, axis=2)
#x = x.astype(np.uint8)
cv2.imshow('temp', x)

```

This is just a small snippet that won’t make sense but should provide some context for what I’ve tried.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [April 22, 2021, 8:26pm UTC](https://forum.opencv.org/t/imshow-and-imwrite-outputs-are-different-and-normalization-is-not-preserving-original-image/2925/2 "2021-04-22T20:26:58Z")

</div>

imwrite and imshow indeed handle floats differently.

scale your values as needed.

I _think_ these are the full scale value ranges (but check docs to be sure):

- imshow: floats: 0.0 to 1.0
- imwrite: floats: 0 to 255

there may be image file formats that store floating point values as is.

you can always dump the floating point data as binary data.

OpenCV has a `FileStorage` class. it’s text-based (XML), so not the most efficient, and I don’t know if that’ll be _exactly_ lossless for floats but it probably is.

---

<div class="post-metadata">

**Author:** ![Dasyud](https://avatars.discourse-cdn.com/v4/letter/d/0ea827/32.png) [@Dasyud](https://forum.opencv.org/u/Dasyud)\
**Post date:** [April 22, 2021, 9:07pm UTC](https://forum.opencv.org/t/imshow-and-imwrite-outputs-are-different-and-normalization-is-not-preserving-original-image/2925/3 "2021-04-22T21:07:04Z")

</div>

I tried several combinations and now I have come to a conclusion as to why my output is bad when I’m trying to normalise it.

Optical flow vectors contain signed values, but when I normalise them to 0 to 1 for imshow, the negative values somehow clip back to the upper interval i.e -1 corresponds to 255 and so on.

How do I scale a signed array (values ranging from around -6 to 6 based on what I’ve seen) to 0 to 1?

For context,  
when I tried normalising using standard methods, the black parts of my image flashed white for a few moments. So thus my conclusion that negative numbers in when fed to the 0-255 constraint results in it taking values from the upper interval.
