Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV's `getTextSize` and `putText` return wrong size and chop letters with lower pixels

I have the following Python code:

FONT = cv2.FONT_HERSHEY_SIMPLEX
FONT_SCALE = 1.0
FONT_THICKNESS = 2
bg_color = (255, 255, 255)
label_color = (0, 0, 0)

label = 'Propaganda'
label_width, label_height = cv2.getTextSize(label, FONT, FONT_SCALE, FONT_THICKNESS)[0]
label_patch = np.zeros((label_height, label_width, 3), np.uint8)
label_patch[:,:] = bg_color

I create a new blank image, with the size returned by getTextSize, and then, I add the text at the bottom-left point, according to the docs, which is x = 0, y = (height - 1) and with the same font, scale and thickness parameters used for getTextSize

cv2.putText(label_patch, label, (0, label_height - 1), FONT, FONT_SCALE, label_color, FONT_THICKNESS)

But when I use imshow or imwrite on the image label_patch, this is the results I get:

enter image description here

It can easily be seen that lowercase p and lowercase g are cut in the middle, such that g and a cannot even be distinguished. How can I make OpenCV's getTextSize return the correct size, and how can I make OpenCV's putText start drawing the text from the actual lowest point?

like image 414
SomethingSomething Avatar asked Jul 11 '18 12:07

SomethingSomething


People also ask

How do I reduce font size in cv2 putText?

How do I reduce font size in cv2 putText? If you take fontScale = 1 for images with size approximately 1000 x 1000, then this code should scale your font correctly.

What is font scale in cv2?

fontScale: Font scale factor that is multiplied by the font-specific base size. color: It is the color of text string to be drawn. For BGR, we pass a tuple. eg: (255, 0, 0) for blue color. thickness: It is the thickness of the line in px.

What does cv2 Line_aa do?

cv. LINE_AA gives anti-aliased line which looks great for curves.


1 Answers

Found the solution, answering myself and hoping others would benefit from it.

It turns out that there is another parameter that getTextSize returns, which is the baseline. The box I created should have taken it into account: its height should be label_height + baseline:

(label_width, label_height), baseline = cv2.getTextSize(label, FONT, FONT_SCALE, FONT_THICKNESS)
label_patch = np.zeros((label_height + baseline, label_width, 3), np.uint8)
label_patch[:,:] = bg_color

Now, adding the text at the same point as before, which means that the baseline pixels will remain below:

cv2.putText(label_patch, label, (0, label_height), FONT, FONT_SCALE, label_color, FONT_THICKNESS)

And the result:

enter image description here

like image 79
SomethingSomething Avatar answered Oct 01 '22 13:10

SomethingSomething