python - 网络摄像头上的水印覆盖非常慢
问题描述
我在网络摄像头上覆盖 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()
解决方案
您不必在-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()
推荐阅读
- javascript - 突出显示最小/最大值表jquery
- cordova - 尝试在 Android 设备上运行 Geolocation 时如何解决 Babel 问题?
- java - ltree postgres type using spring data jpa -- 在 postgres 中定义函数和强制转换后出现语法错误
- python - Python - 仅从文本文件中读取最后一行
- python - 索引 0 处的无效数组元素:需要 datetime.date 或 datetime.datetime 实例,得到 'int' asyncpg
- alpacajs - 羊驼 - 是否有 onReady 表格?
- flutter - Flutter 改变系统导航栏图标亮度
- angular - 子路由组件看不到的可重用组件
- javascript - 如何添加到 chrome 存储中已经存在的数组?
- reactjs - 从 React 中的配置文件动态命名组件