首页 > 解决方案 > 网络摄像头上的水印覆盖非常慢

问题描述

我在网络摄像头上覆盖 png 图像的代码。我希望只有当它们进入面部覆盖区域时才能检测到它们。这将限制从更远距离检测到不必要的误报人脸。只有当人脸进入该区域时,才会检测到人脸,否则不会检测到人脸。(人脸检测仍有待加入)

import numpy as np
import cv2,os

def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
     dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation = inter)
    return resized


cap = cv2.VideoCapture(0)

img_path = 'face.png'
logo = cv2.imread(img_path, -1)
watermark = image_resize(logo, height=500)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2BGRA)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
    frame_h, frame_w, frame_c = frame.shape
    overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')
  
    watermark_h, watermark_w, watermark_c = watermark.shape
    offset = 10
    h_offset = frame_h - watermark_h - offset
    w_offset = frame_w - watermark_w - offset

    for i in range(0, watermark_h):
        for j in range(0, watermark_w):
            overlay[h_offset + i, w_offset+ j] = watermark[i,j]

    cv2.addWeighted(overlay, 0.75, frame, 1.0, 0, frame)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
    # Display the resulting frame
    cv2.imshow('frame',frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

这段代码的问题是它非常慢。如何加快速度?人脸.PNG图片

标签: pythonopencvface-detection

解决方案


您不必在-loop 中overlay一次又一次地创建。 您只能在循环之前创建一次。然后代码工作得很快。while
while

import os
import numpy as np
import cv2

def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation = inter)
    return resized

# --- main ---

cap = cv2.VideoCapture(0)

img_path = 'face.png'

logo = cv2.imread(img_path, -1)

watermark = image_resize(logo, height=500)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2BGRA)
watermark_h, watermark_w, watermark_c = watermark.shape

# read first frame to get shape

ret, frame = cap.read()
frame_h, frame_w, frame_c = frame.shape
print(frame_h, frame_w)

overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')

offset = 10
h_offset = frame_h - watermark_h - offset
w_offset = frame_w - watermark_w - offset

for i in range(0, watermark_h):
    for j in range(0, watermark_w):
        overlay[h_offset + i, w_offset+ j] = watermark[i,j]

while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)    
 
    cv2.addWeighted(overlay, 0.75, frame, 1.0, 0, frame)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)

    # Display the resulting frame
    cv2.imshow('frame',frame)

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

cap.release()
cv2.destroyAllWindows()

顺便提一句:

它的工作速度如此之慢,也是因为您使用for-loops 来分别移动每个像素。如果您使用numpy函数来复制它,那么它可以工作得更快。

overlay[h_offset:h_offset+watermark_h, w_offset:w_offset+watermark_w] = watermark[h_start:h_start+watermark_h, w_start:w_start+watermark_w]

因为对于我的相机(640x480)h_offset来说-30,它需要重新计算。

import os
import numpy as np
import cv2

def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation = inter)
    return resized

# --- main ---

cap = cv2.VideoCapture(0)

img_path = 'face.png'

logo = cv2.imread(img_path, -1)

watermark = image_resize(logo, height=500)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2BGRA)
watermark_h, watermark_w, watermark_c = watermark.shape
print(watermark_h, watermark_w, watermark_c)

while True:

    # Capture frame-by-frame
    ret, frame = cap.read()
    
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)    
    frame_h, frame_w, frame_c = frame.shape
    print(frame_h, frame_w)

    overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')

    offset = 10
    h_start = 0
    w_start = 0
    h_offset = frame_h - watermark_h - offset
    w_offset = frame_w - watermark_w - offset

    print('before:', h_offset, h_offset+watermark_h, w_offset, w_offset+watermark_w)

    print('h_offset:', h_offset)
    if h_offset < 0:
        h_start = -h_offset
        watermark_h -= h_start
        h_offset = 0 

    print('after:', h_offset, h_offset+watermark_h, w_offset, w_offset+watermark_w)

    overlay[h_offset:h_offset+watermark_h, w_offset:w_offset+watermark_w] = watermark[h_start:h_start+watermark_h, w_start:w_start+watermark_w]
 
    cv2.addWeighted(overlay, 0.75, frame, 1.0, 0, frame)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
    
    # Display the resulting frame
    cv2.imshow('frame',frame)
    
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

推荐阅读