nobody
nobody

Reputation: 835

opencv in python: a very strange error. What is the difference between creating a new image with np.zeros and simply copying the existing image?

Suppose I have a image loaded in python. I understand since a colored image in python is no more than a three-dimensional array, I attempted to create a new image that only contains a few selected pixel values from the loaded image. However this is really not working well. Please allow me to demonstrate with a very simple example.

Suppose that my original image "img" is a 20x20x3 matrix with all elements equal to 0.

img2 = np.zeros(img.shape)
img2[0:5,0:5] = [100,0,0]

With this I am assuming that the output on imshow should have a blacked out image but with a blue square on the top left corner. This is working well.

However, if I change to

img2 = np.zeros(img.shape)
img2[0:5,0:5] = [100,100,1]

This shows a completely white square on the top left corner, with the rest blacked out. However, BGR = [100,100,1] (opencv in python processes image in BGR space instead of RGB) should not be white!

This problem is immediately fixed with

img2 = img.copy()
img2[0:5,0:5] = [100,100,1]

with this I get a square on the top left corner with the correct pixel value.

Could someone let me know what is the fundamental difference between creating a new numpy ndarray with exactly the same shape as the original image, and fill in the desired values; and simply making a copy of the original img matrix? Why it works well with BGR = [100,0,0] but not with [100,100,1]?

Thanks

Upvotes: 2

Views: 765

Answers (1)

Emmanuelle Gouillart
Emmanuelle Gouillart

Reputation: 839

Could you please explain how you created img as well? One reason for the different behavior might be that img2 does not have the same data type (img2.dtype) as img, and that the visualization function that you use (could you also tell us which function you call to display the image?) has a different behavior when you pass integer-type or floating-point-type images (like, for integer-type, the color range will be between 0 and 255, while for floats, it will be between img2.min() and img2.max().

When you're using np.zeros, if you don't specify the dtype keyword argument the output array will have a float dtype. On the other hand, using np.zeros_like keeps the same dtype as the input array. I would suspect that in your example img is an image of integers, and that your visualization procedure behaves differently for integer and float images.

Upvotes: 2

Related Questions