繁体   English   中英

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

[英]How to change the opacity of boxes (cv2.rectangle)?

我在 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%。 我的问题是:如何更改不透明度?

最终结果应如下所示:

期望的结果

我想为@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

在此处输入图片说明

编辑:由于这个答案似乎有一些重要性,我决定再次编辑它,结合ZdaR 答案中的适当混合,最初是对我原始答案的改进(如果有兴趣,请查看时间表)。 此外,我结合了Jon 的评论以包含一个非矩形形状的示例。


至少从我的角度来看,像cv2.rectangle这样的内置函数不支持不透明度,即使在 BGRA 图像上,请参见此处 因此,正如我在链接的答案中所描述的,实现您想要的唯一可能性是使用cv2.addWeighted函数。 您可以简单地设置一个空白蒙版图像,并在其上绘制所有可能的形状。 这样做,您还可以将其用作实际蒙版以将混合仅限于该部分。

一个例子可能是:

import cv2
import numpy as np

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

# Initialize blank mask image of same dimensions for drawing the shapes
shapes = np.zeros_like(img, np.uint8)

# Draw shapes
cv2.rectangle(shapes, (5, 5), (100, 75), (255, 255, 255), cv2.FILLED)
cv2.circle(shapes, (300, 300), 75, (255, 255, 255), cv2.FILLED)

# Generate output by blending image with shapes image, using the shapes
# images also as mask to limit the blending to those parts
out = img.copy()
alpha = 0.5
mask = shapes.astype(bool)
out[mask] = cv2.addWeighted(img, alpha, shapes, 1 - alpha, 0)[mask]

# Visualization
cv2.imshow('Image', img)
cv2.imshow('Shapes', shapes)
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

原始帕丁顿img

图片

中间图像上绘制形状shapes

形状

并且,最终结果out

出去

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

希望有帮助!

只需安装 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 上测试的示例和完整的演示在这里

莉娜.jpg

在此处输入图片说明

简单的.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)

出.jpg

在此处输入图片说明

另一个.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)

出.jpg

在此处输入图片说明

一个更简单的解决方案(虽然在内存方面效率稍低)是:

  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上的帖子

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM