How to make black background in cv2.putText with Python OpenCV

Viewed 20267

I have a project of opencv where on the frame I am displaying some text using cv2.putText(). Currently it looks like below:

enter image description here

As you can see on the top left corner, the text is present but its not clearly visible. Is it possible to make background black so that the text will then appear good. Something like below image:

enter image description here

Even if the black background covers till right side of the frame, that is also fine. Below is the code I am using for putting text on frame:

cv2.putText(frame, "Data: N/A", (5, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)
cv2.putText(frame, "Room: C1", (5, 60), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)

Is there any prebuilt method/library available in opencv which can do this. Can anyone please suggest a good way?

4 Answers

Use this function:

import cv2

def draw_text(img, text,
          font=cv2.FONT_HERSHEY_PLAIN,
          pos=(0, 0),
          font_scale=3,
          font_thickness=2,
          text_color=(0, 255, 0),
          text_color_bg=(0, 0, 0)
          ):

    x, y = pos
    text_size, _ = cv2.getTextSize(text, font, font_scale, font_thickness)
    text_w, text_h = text_size
    cv2.rectangle(img, pos, (x + text_w, y + text_h), text_color_bg, -1)
    cv2.putText(img, text, (x, y + text_h + font_scale - 1), font, font_scale, text_color, font_thickness)

    return text_size

Then you can invoke the function like this:

image = 127 * np.ones((100, 200, 3), dtype="uint8")
pos = (10, 10)
w, h = draw_text(image, "hello", pos=(10, 10))
draw_text(image, "world", font_scale=4, pos=(10, 20 + h), text_color_bg=(255, 0, 0))
cv2.imshow("image", image)
cv2.waitKey()

draw text with background in OpenCV

note that by default it paints a black background, but you can use a different color if you want.

There's no prebuilt method but a simple appraoch is to use cv2.rectangle + cv2.putText. All you need to do is to draw the black rectangle on the image followed by placing the text. You can adjust the x,y,w,h parameters depending on how large/small you want the rectangle. Here's an example:

Input image:

enter image description here

Result:

enter image description here

import cv2
import numpy as np

# Load image, define rectangle bounds
image = cv2.imread('1.jpg')
x,y,w,h = 0,0,175,75

# Draw black background rectangle
cv2.rectangle(image, (x, x), (x + w, y + h), (0,0,0), -1)

# Add text
cv2.putText(image, "THICC flower", (x + int(w/10),y + int(h/2)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)

# Display
cv2.imshow('image', image)
cv2.waitKey()

Here is one way to do that in Python OpenCV.

  • Read the input
  • Create an image of your desired background color that is the same size as the input
  • Draw your text on the background image
  • Get the bounding rectangle for the text region
  • Copy the text region from the background color image to a copy of the input image
  • Save the results

Input:

enter image description here

import cv2
import numpy as np

# load image
img = cv2.imread("zelda1.jpg")

# create same size image of background color
bg_color = (0,0,0)
bg = np.full((img.shape), bg_color, dtype=np.uint8)

# draw text on bg
text_color = (0,0,255)
cv2.putText(bg, "Data: N/A", (5,30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 0.75, text_color, 1)

# get bounding box
# use channel corresponding to color so that text is white on black background
x,y,w,h = cv2.boundingRect(bg[:,:,2])
print(x,y,w,h)

# copy bounding box region from bg to img
result = img.copy()
result[y:y+h, x:x+w] = bg[y:y+h, x:x+w]

# write result to disk
cv2.imwrite("zelda1_background_text.jpg", bg)
cv2.imwrite("zelda1_text.jpg", result)

# display results
cv2.imshow("TEXT", bg)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()


Text on background color image:

enter image description here

Text on input image:

enter image description here

P.S. You can adjust the bounding rectangle (x,y,w,h) values to add some padding if you want when you do the crop.

import cv2 \
import numpy as np

#### Load image, define rectangle bounds
image = cv2.imread(r'C:\Users\Bharath\Downloads\test.jpg')

#### overlay space
x,y,w,h = 40,30,300,60


#### alpha, the 4th channel of the image
alpha = 0.3

overlay = image.copy()
output = image.copy()


##### corner
cv2.rectangle(overlay, (x, x), (x + w, y + h), (0,0,0), -1)

##### putText
cv2.putText(overlay, "HELLO WORLD..!", (x + int(w/10),y + int(h/1.5)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)

#### apply the overlay
cv2.addWeighted(overlay, alpha, output, 1 - alpha,0, output)


##### Display
cv2.imshow("Output", output)\
cv2.waitKey(0)

`

input enter image description here

outputenter image description here

Related