在 OpenCV 中设置 ROI 之外的背景颜色

Posted

技术标签:

【中文标题】在 OpenCV 中设置 ROI 之外的背景颜色【英文标题】:Set background color outside ROI in OpenCV 【发布时间】:2021-12-03 19:04:41 【问题描述】:

我成功显示了视频源,并尝试将 ROI 外部区域的背景颜色从黑色更改为蓝色,但屏幕仍然显示黑色背景。请帮我解决问题。任何帮助将不胜感激。

原始代码

import numpy as np
from cv2 import cv2
'''
ML object detection algo(haarcascade)used to identify objects. 
the XML file consists of trained Haar Cascade models.
'''
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#initialize video from the webcam
video = cv2.VideoCapture(1)

while True:
# ret tells if the camera works properly. Frame is an actual frame from the video feed
    ret, frame= video.read()
    # print(cv2.VideoCapture(0).isOpened())
    # make sure port is working and read the image
    if frame is not None and video.isOpened():
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # Detect the faces within the subregions of the image in scales
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=6)
        # Draw the rectangle around each face
        for (x, y, w, h) in faces:
            #Use the coordinates to find the center of the face and from that point draw a rectangle of radius w/2 or h/2.
            center_coordinates = x + w // 2, y + h // 2
            radius = w // 2 # or can be h / 2 or can be anything based on your requirements
            #background color(black) 
            mask=np.zeros(frame.shape[:2] , dtype="uint8") 
         
            # Draw the desired region to crop out in white 
            cv2.circle(mask, center_coordinates, radius, (255,255,255),-1)    
            masked=cv2.bitwise_and(frame,frame,mask=mask)
            cv2.imshow('mask applied',masked)
        if cv2.waitKey(30) & 0xff==27:
            break
video.release()
cv2.destroyAllWindows()

上面的代码检测并在黑色背景上的圆形蒙版中显示人脸。但是如上所述,圆形 ROI 外的背景颜色应该是蓝色的。

我尝试用下面的代码替换 mask=np.zeros(frame.shape[:2], dtype="uint8") 并失败。 Frame.shape[0:2] 甚至不包括通道,我一开始不知道如何更改颜色。

mask=np.ones(frame.shape[0:2], dtype="uint8")
mask[:,:,0]=255
mask[:,:,1]=0
mask[:,:,2]=0

我还尝试创建一个圆形蒙版图像,然后将其放在另一个图像上,结果发现它会导致同样的问题。

import numpy as np
from cv2 import cv2
'''
ML object detection algo(haarcascade)used to identify objects. 
the XML file consists of trained Haar Cascade models.
'''
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#initialize video from the webcam
video = cv2.VideoCapture(1)
print(cv2.VideoCapture(1).isOpened())

while True:
# ret tells if the camera works properly. Frame is an actual frame from the video feed
    ret, frame= video.read()
    # print(cv2.VideoCapture(0).isOpened())
    # make sure port is working and read the image
    if frame is not None and video.isOpened():
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # Detect the faces within the subregions of the image in scales
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=6)
        # Draw the rectangle around each face
        for (x, y, w, h) in faces:
            #Use the coordinates to find the center of the face and from that point draw a rectangle of radius w/2 or h/2.
            center_coordinates = x + w // 2, y + h // 2
            radius = w // 2 # or can be h / 2 or can be anything based on your requirements
            #background color(black) 
            mask=np.zeros(frame.shape[:2] , dtype="uint8") 
            # create blue colored background
            color = np.full_like(frame, (255,0,0))
           
            # Draw the desired region to crop out in white 
            roi=cv2.circle(mask, center_coordinates, radius, (255,255,255),-1)    
            masked=cv2.bitwise_and(frame,frame,mask=mask)
            mask_blue=cv2.bitwise_and(color,color,mask=mask-roi)
            # combine the two masked images
            result = cv2.add(masked,mask_blue)
            cv2.imshow('result',result)
        if cv2.waitKey(30) & 0xff==27:
            break
video.release()
cv2.destroyAllWindows()

【问题讨论】:

【参考方案1】:

根据您的要求,我已将您的代码更改如下。这里我多加了一行

masked[np.where((masked==[0,0,0]).all(axis=2))]=[255,0,0]

您可以将黑色区域的像素值更改为任何特定颜色。

import numpy as np
import cv2
'''
ML object detection algo(haarcascade)used to identify objects. 
the XML file consists of trained Haar Cascade models.
'''
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades +'haarcascade_frontalface_default.xml')
#initialize video from the webcam
video = cv2.VideoCapture(0)
print(cv2.VideoCapture(0).isOpened())

while True:
# ret tells if the camera works properly. Frame is an actual frame from the video feed
    ret, frame= video.read()
    # print(cv2.VideoCapture(0).isOpened())
    # make sure port is working and read the image
    if frame is not None and video.isOpened():
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # Detect the faces within the subregions of the image in scales
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=6)
        # Draw the rectangle around each face
        for (x, y, w, h) in faces:
            #Use the coordinates to find the center of the face and from that point draw a rectangle of radius w/2 or h/2.
            center_coordinates = x + w // 2, y + h // 2
            radius = w // 2 # or can be h / 2 or can be anything based on your requirements
            #background color(black) 
            mask=np.zeros(frame.shape[:2] , dtype="uint8") 
            
            # Draw the desired region to crop out in white 
            roi=cv2.circle(mask, center_coordinates, radius, (255,255,255),-1)    
            masked=cv2.bitwise_and(frame,frame,mask=mask)
            masked[np.where((masked==[0,0,0]).all(axis=2))]=[255,0,0]
            cv2.imshow('result',masked)
        if cv2.waitKey(30) & 0xff==27:
            break
video.release()
cv2.destroyAllWindows()

【讨论】:

以上是关于在 OpenCV 中设置 ROI 之外的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

关于opencv中cv::Mat设置roi

如何在 loadView 中设置背景颜色?

在 PDCurses 中设置整个窗口的背景颜色

如何在卡片背景中设置多种不同的颜色

如何在 TTTAtributedLabel 中设置范围的背景颜色

如何在OpenGL中设置背景颜色