提取前景时如何避免颜色泄漏?

时间:2019-05-26 21:44:06

标签: python opencv

我需要从已知的静态背景中提取前景(在网络摄像头上)。现在,我使用cv2.accumulateWeighted()使用背景的前30帧获得加权平均值,然后将当前帧与背景进行比较。 (全部为灰度)

问题是程序对背景是什么有很多困惑,并且经常将我身体的某些部位标记为背景(主要是在背景色接近我的肤色时发生),我相信这是由于颜色泄漏。

代码

def getBackground(gray, aWeight=0.2):

    global bg

    if bg is None:
        bg = gray.copy().astype(float)
        return

    cv2.accumulateWeighted(gray, bg, aWeight)

def extractForeground(gray, threshold=25):
    global bg

    diff = cv2.absdiff(bg.astype('uint8'), gray)

    thresholded = cv2.threshold(diff,
                                threshold,
                                255,
                                cv2.THRESH_BINARY)[1]

    kernel = np.ones((3,3),np.uint8)

    thresholded = cv2.erode(thresholded,kernel,iterations = 2)
    thresholded = cv2.dilate(thresholded,kernel,iterations = 2)


    return thresholded

#global
bg = None

cap = cv2.VideoCapture(0)
numFrames = 0


while True:

    ret,frame = cap.read()
    frame = imutils.resize(frame, width = 700)

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    if (numFrames<30):
        getBackground(gray)

    else:
        fg = extractForeground(gray)

    numFrames += 1

    if cv2.waitKey(1) & 0xFF == ord('q'):
    break

即使背景和前景颜色相对接近,我也需要改进此步骤以准确提取前景。如何避免颜色泄漏?

预先感谢

1 个答案:

答案 0 :(得分:0)

在将其传递到前景提取之前,请先尝试对灰度图像使用高斯模糊。我通常使用内核(15,15),然后对其进行调整,以查看其是否提供更好的结果。 另一种方法是尝试使用多张图像提取背景:

  1. 使用您的extractForeground函数获取被视为前景的区域。然后将前景区域像素替换为np.nan。
  2. 像这样保存多张图像后,将其添加到n张图像中。例如:(n,image.shape)。然后使用np.nanmean计算平均背景(nanmean计算平均像素,而不是np.nan的像素)=> U获取其中没有前景的背景。
  3. 拍摄下一张图像和具有平均背景的absdif以获取前景。