如何更改盒子的不透明度(cv2.rectangle)?

时间:2019-06-06 06:33:40

标签: python opencv

我在OpenCV中绘制了一些矩形并将文本放入其中。我的一般方法如下:

# Draw rectangle    p1(x,y)    p2(x,y)    Student name box
cv2.rectangle(frame, (500, 650), (800, 700), (42, 219, 151), cv2.FILLED )
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (510, 685), font, 1.0, (255, 255, 255), 1

到目前为止一切正常。唯一的是,所有框中的不透明度均为100%。我的问题是:如何更改不透明度?

最终结果应如下所示:

Desired outcome

4 个答案:

答案 0 :(得分:1)

编辑:尽管我的解决方案可能会起作用,但我强烈建议使用ZdaR's answer,因为这样可以在将框与基础子图像正确混合方面提供更好的结果。


至少从我的角度来看,cv2.rectangle之类的内置函数甚至在BGRA图像上也不支持不透明度,请参见here。因此,正如我在链接的答案中所述,要实现的唯一可能性就是使用cv2.addWeighted函数。

一个例子可能是:

import cv2
import numpy as np

# Load image
img = cv2.imread('images/paddington.png')

# Initialize black image of same dimensions for drawing the rectangles
blk = np.zeros(img.shape, np.uint8)

# Draw rectangles
cv2.rectangle(blk, (5, 5), (100, 75), (255, 255, 255), cv2.FILLED)

# Generate result by blending both images (opacity of rectangle image is 0.25 = 25 %)
out = cv2.addWeighted(img, 1.0, blk, 0.25, 1)

cv2.imshow('Image', img)
cv2.imshow('Rects', blk)
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

原始的帕丁顿img

img

blk上绘制矩形的中间图像:

blk

然后,最终结果out

out

绘制矩形并混合图像后,您可以像以前一样添加文本。

希望有帮助!

答案 1 :(得分:1)

我想在@HansHirse答案中添加一个小的优化,而不是为整个图像创建画布,我们可以首先从src图像中裁剪矩形,然后将其与cv2.addWeighted结果交换为:

import cv2
import numpy as np

img = cv2.imread("lena.png")

# First we crop the sub-rect from the image
x, y, w, h = 100, 100, 200, 100
sub_img = img[y:y+h, x:x+w]
white_rect = np.ones(sub_img.shape, dtype=np.uint8) * 255

res = cv2.addWeighted(sub_img, 0.5, white_rect, 0.5, 1.0)

# Putting the image back to its position
img[y:y+h, x:x+w] = res

enter image description here

答案 2 :(得分:1)

只需安装pyshine并使用putBText,它具有以下输入和输出。

pip install pyshine

"""

Inputs:
    img: cv2 image img
    text_offset_x, text_offset_x: X,Y location of text start
    vspace, hspace: Vertical and Horizontal space between text and box boundaries
    font_scale: Font size
    background_RGB: Background R,G,B color
    text_RGB: Text R,G,B color
    font: Font Style e.g. cv2.FONT_HERSHEY_DUPLEX,cv2.FONT_HERSHEY_SIMPLEX,cv2.FONT_HERSHEY_PLAIN,cv2.FONT_HERSHEY_COMPLEX
          cv2.FONT_HERSHEY_TRIPLEX, etc
    thickness: Thickness of the text font
    alpha: Opacity 0~1 of the box around text
    gamma: 0 by default

Output:
    img: CV2 image with text and background
"""

在Python3上测试过的示例,完整的示例为here

lena.jpg

enter image description here

simple.py

import pyshine as ps
import cv2
image = cv2.imread('lena.jpg')
text  =  'HELLO WORLD!'
image =  ps.putBText(image,text,text_offset_x=20,text_offset_y=20,vspace=10,hspace=10, font_scale=2.0,background_RGB=(0,250,250),text_RGB=(255,250,250))
cv2.imshow('Output', image)
cv2.imwrite('out.jpg',image)
cv2.waitKey(0)

out.jpg

enter image description here

another.py

import pyshine as ps
import cv2
import time
image = cv2.imread('lena.jpg')


text  =  'ID: '+str(123)
image = ps.putBText(image,text,text_offset_x=20,text_offset_y=20,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(1,1,1))
text = str(time.strftime("%H:%M %p"))
image = ps.putBText(image,text,text_offset_x=image.shape[1]-170,text_offset_y=20,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(1,1,1))

text  =  '6842'
image = ps.putBText(image,text,text_offset_x=80,text_offset_y=372,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(255,255,255))

text  =  "Lena Fors'en"
image = ps.putBText(image,text,text_offset_x=80,text_offset_y=425,vspace=20,hspace=10, font_scale=1.0,background_RGB=(20,210,4),text_RGB=(255,255,255))

text  =  'Status: '
image = ps.putBText(image,text,text_offset_x=image.shape[1]-130,text_offset_y=200,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(255,255,255))
text  =  'On time'
image = ps.putBText(image,text,text_offset_x=image.shape[1]-130,text_offset_y=242,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(255,255,255))


text  =  'Attendence: '
image = ps.putBText(image,text,text_offset_x=image.shape[1]-200,text_offset_y=394,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(255,255,255))
text  =  '96.2%      '
image = ps.putBText(image,text,text_offset_x=image.shape[1]-200,text_offset_y=436,vspace=10,hspace=10, font_scale=1.0,background_RGB=(228,225,222),text_RGB=(255,255,255))

cv2.imshow('Output', image)
cv2.imwrite('out.jpg',image)
cv2.waitKey(0)

out.jpg

enter image description here

答案 3 :(得分:0)

一个更简单的解决方案(尽管在内存方面效率较低):

  1. 创建原始图像的副本
  2. 在原始图像上绘制所需的形状/文字
  3. 通过以下方式获取叠加层:alpha*img + (1-alpha)*img_cpy

通过这种方式,每个原始像素都不会更改其值(因为alpha * px +(1-alpha)px = px),而绘制的像素将受到覆盖的影响。

这消除了执行其他答案中所见的作物和讨厌的计算的需要。

...并应用于OP的代码:

frame_cpy = frame.copy()
cv2.rectangle(frame, (500, 650), (800, 700), (42, 219, 151), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (510, 685), font, 1.0, (255, 255, 255), 1)
alpha = 0.4
frame_overlay=cv2.addWeighted(frame, alpha, frame_cpy,1-alpha, gamma=0)
cv2.imshow("overlay result",frame_overlay)
cv2.waitKey(0)

免责声明:此答案的灵感来自www.pyimagesearch.com

上的一条帖子