It looks like the main issue is converting image type to float
.
Assume (please verify it):
im[0]
is 16-bit grayscale, and im[0].dtype
is dtype('uint16')
.
image = im[0]/255.0
implies that you want to convert the range from 16-bit grayscale to the the range of uint8
.
Note: for converting the range from [0, 2^16-1] to [0, 255] you need to divide by (2**16-1)/255
= 257.0
. But this is not the main issue.
The main issue is converting the type to float
.
The valid range of float
images in OpenCV is [0, 1].
All values above 1.0
are white pixels, and 0.5
is a gray pixel.
You can keep the image type uint16
- you don't have to convert it to uint8
.
A white text color for uint16
type is 2**16-1
= 65535
(not 255).
Here is code sample that works with 16-bit grayscale (and uint16
type):
import numpy as np
import cv2
im = np.full((80, 80), 10000, np.uint16) # 16 bits grayscale synthetic image - set all pixels to 10000
cv2.circle(im, (40, 40), 10, 0, 20, cv2.LINE_8) # draw black cicle - synthetic image
#image = im[0]/255.0 #where im is just an np array of images (which are 80x80 np arrays)
image = im #where im is just an np array of images (which are 80x80 np arrays)
color = 2**16-1 # 65535 is white color for 16 bis image
# Using cv2.putText() method
image = cv2.putText(image, 'Out:16', (40, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.3, color, 1, cv2.LINE_AA)
# Displaying the image
cv2.imshow("image", image)
cv2.waitKey()
The above code creates synthetic 16-bit grayscale for testing.
Converting from 16-bit grayscale to 8-bit grayscale:
# https://stackoverflow.com/questions/11337499/how-to-convert-an-image-from-np-uint16-to-np-uint8
uint8_image = cv2.convertScaleAbs(image, alpha=255.0/(2**16-1)) # Convent uint16 image to uint8 image (2**16-1 scaled to 255)
The above conversion assumes image
is full range 16 bits (pixel range [0, 65535]).
About the font:
OpenCV is computer vision oriented, and text drawing limited.

Why is the image black?
It's hard to answer without knowing the values of im[0]
.
- It could be that
im[0]
is not a 16-bit grayscale at all.
- It could be that the values of
im[0]
are very small.
- It could be that the type of
im[0]
is not uint16
.
Drawing text using Pillow (PIL):
The quality of the small text is much better compared to OpenCV.
You can find for about quality text rendering here.
Continue with the uint8
image:
pil_image = Image.fromarray(uint8_image)
draw = ImageDraw.Draw(pil_image)
# specified font size
font = ImageFont.truetype('./arial.ttf', 10)
text = 'fyp:16'
# drawing text size
draw.text((5, 5), text, 255, font = font, align ="left")
pil_image.show()
Result:

I don't really know the reason your text looks wired compared to above result.