Ask Your Question
2

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

asked 2019-12-11 14:24:21 -0600

BStrum gravatar image

updated 2019-12-14 11:13:48 -0600

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

edit retag flag offensive close merge delete

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 ( 2019-12-11 19:24:10 -0600 )edit

Check this link reshape

supra56 gravatar imagesupra56 ( 2019-12-11 21:35:14 -0600 )edit

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

mvuori gravatar imagemvuori ( 2019-12-12 00:56:05 -0600 )edit
berak gravatar imageberak ( 2019-12-12 01:57:49 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2019-12-12 01:51:43 -0600

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
edit flag offensive delete link more

Comments

1

THIS WORKS!!! Thanks

BStrum gravatar imageBStrum ( 2019-12-12 10:22:28 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-12-11 14:24:21 -0600

Seen: 8,869 times

Last updated: Dec 14 '19