First time here? Check out the FAQ!

Ask Your Question
2

cv2.imshow and cv2.imwrite show different output from the same array[SOLVED]

asked Dec 11 '19

BStrum gravatar image

updated Dec 14 '19

supra56 gravatar image

I am creating an image from a numpy array which was created by a style transfer .net

output = net.forward()

The output is the renormalized from the.net processing.

output = output.reshape((3, output.shape[2], output.shape[3]))
output[0] += 103.939
output[1] += 116.779
output[2] += 123.680
output = output.transpose(1, 2, 0)

When I display this with cv2.imshow I get the correct image image description

Now i try and convert this to an image file for saving and display: First I rescale the image back up to the 0 -255 integer range with:

output = (output * 255).astype(np.uint8)

Then save it with:

cv2.imwrite(path + "/" + "Test_Out" + '.jpg', output)

The latter image has color artifacts that I can't explain. (I don't have enough posts to display the images :( )

Any ideas how to properly display the numpy array??! image description

Preview: (hide)

Comments

I'm not sure, but does the array have 4 channels? If so, try setting the last one (which may be treated as a transparency array) to a constant 255.

Tetragramm gravatar imageTetragramm (Dec 12 '19)edit

Check this link reshape

supra56 gravatar imagesupra56 (Dec 12 '19)edit

Of course the array is not the same if you do an operation to it after imshow...

mvuori gravatar imagemvuori (Dec 12 '19)edit
berak gravatar imageberak (Dec 12 '19)edit

1 answer

Sort by » oldest newest most voted
3

answered Dec 12 '19

berak gravatar image

your problem is here:

output = (output * 255).astype(np.uint8)

numpy does not apply saturation when you convert to uint8, but does modulo overflow, as an example:

>>> a = np.array([1.1],dtype=np.float32)
>>> a * 255
array([280.5], dtype=float32)    <-- problem
>>> b = (a * 255).astype(np.uint8)
>>> b
array([24], dtype=uint8)    <-- problem
>>> np.clip(a*255,0,255)
array([255.], dtype=float32)

you should clip() your float array before the conversion:

output = np.clip(output * 255, 0, 255) # proper [0..255] range
output = output.astype(np.uint8)  # safe conversion
Preview: (hide)

Comments

1

THIS WORKS!!! Thanks

BStrum gravatar imageBStrum (Dec 12 '19)edit

Question Tools

1 follower

Stats

Asked: Dec 11 '19

Seen: 9,427 times

Last updated: Dec 14 '19