Reputation: 373
I was doing some testing based on my understanding from reading the documentation but stumble upon this.
Source: NumPy convert 8-bit to 16/32-bit image
i = cv2.imread(imgNameIn, cv2.CV_LOAD_IMAGE_COLOR) # Need to be sure to have a 8-bit input
img = np.array(i, dtype=np.uint16) # This line only change the type, not values
img *= 256 # Now we get the good values in 16 bit format
But from what I read here http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html
To scale down from 32bits to 8 bits one have to divide by 255 instead of 256 mentioned above which I got from the other post? This code below is what I am trying to play around with.
Would appreciate if anyone able to check if I have done the scaling correctly. I am asking this question mainly to confirm whether the supposed casting value is 255 or 256?
Upvotes: 2
Views: 3060
Reputation: 3645
I have to disagree with the answer to the question you link. Format uint8
can represent 256 values of integers i.e., integers from 0 to 255 (2^8 - 1)
. 256 cannot be represented as uint8
. uint16
will range from 0 to (2^16 - 1) = 65535
.
Therefore, if you want a 16-bit, images with 65535 color levels and if the intensity values of the images are in the range [0, 1]
when you read the image and in format float
, you need to multiply the values by 65535 and to and then to convert the array to uint16
.
It is good practice to cast the type of your end result as the very last step of the operations you perform. This is mainly for two reasons: - If you perform divisions or multiplications by float, the result will return a float and you will need to change the type again. - In general (in the mathematical sense of the term), a transformation from float to integer introduces errors. Casting the type at the very end of the operations prevents error propagation.
To go back to 8-bit i.e., 256 color levels, you need to multiply all values by 255 / 65535
.
The same reasoning holds for 32-bit images with 2^32 = 4,294,967,296
possible intensity values, i.e, values in the range [0, 4294967295]
. These number becoming big, you will rather work with 32-bit images in the float format where values are contained in the range [0, 1]
.
PS: I found your code quite confusing and did not go through in detail. Understanding that the 8/16/32/64-bit format is a representation of the number of possible intensity levels in the image is the key that should allow you to understand the transformations you are doing on the images.
Upvotes: 3