伙计们,我在将视频叠加到网络摄像头时遇到问题。我可以打开网络摄像头而没有任何问题或错误,但我的视频没有显示。我正在尝试在特定的 x-y 坐标中播放我的视频。我从另一个 stackoverflow 问题中获取了我的大部分代码,但我找不到它,所以我不能在这里提及它。
那么有人可以帮我解决这个问题吗?为什么我的视频没有在我的网络摄像头中播放? 我有以下代码:
from os.path import sep
import cv2 as cv2
# load the overlay image. size should be smaller than video frame size
img = cv2.VideoCapture('photos' + sep + 'Baslksz-3.mp4')
# Get Image dimensions
width = img.set(cv2.CAP_PROP_FRAME_WIDTH, 150) # float `width`
height = img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)
# Start Capture
cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 30)
frame_vid = img.read()
# Decide X,Y location of overlay image inside video frame.
# following should be valid:
# * image dimensions must be smaller than frame dimensions
# * x+img_width <= frame_width
# * y+img_height <= frame_height
# otherwise you can resize image as part of your code if required
x = 50
y = 50
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# add image to frame
frame[ y:y+width , x:x+height ] = img
'''
tr = 0.3 # transparency between 0-1, show camera if 0
frame = ((1-tr) * frame.astype(np.float) + tr * frame_vid.astype(np.float)).astype(np.uint8)
'''
# Display the resulting frame
cv2.imshow('frame',frame)
# Exit if ESC key is pressed
if cv2.waitKey(20) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
答案 0 :(得分:2)
让我开始逐步分析代码。
img = cv2.VideoCapture('photos' + sep + 'Baslksz-3.mp4')
上面的代码看起来不错,但如果你把它作为字符串命名会更好
video_name = 'photos' + sep + 'Baslksz-3.mp4'
img = cv2.VideoCapture(video_name)
# Get Image dimensions
width = img.set(cv2.CAP_PROP_FRAME_WIDTH, 150) # float `width`
height = img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)
现在什么是 width
和 height
变量?
# Get Image dimensions
width = img.set(cv2.CAP_PROP_FRAME_WIDTH, 150) # float `width`
height = img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)
print(width)
print(height)
结果是:
False
False
您似乎想将 width
和 height
设置为维度 (150, 150)
。如果单独初始化会更好
# Get Image dimensions
img.set(cv2.CAP_PROP_FRAME_WIDTH, 150) # float `width`
img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)
width = 150
height = 150
# Start Capture
cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 30)
为什么要两次初始化 cap
变量?
frame_vid = img.read()
你为什么初始化 frame_vid
你没有在代码中的任何地方使用?
while (True):
# Capture frame-by-frame
ret, frame = cap.read()
frame[y:y + width, x:x + height] = img
上面的代码没有任何意义,只要您的网络摄像头打开,您就想显示您的视频。您也没有检查当前网络摄像头框架是否返回。您还将 VideoCapture
变量设置为数组?
while cap.isOpened():
# Capture frame-by-frame
ret, frame = cap.read()
现在您正在获取帧,只要您的网络摄像头打开,那么您需要检查网络摄像头帧是否返回。如果网络摄像头帧返回,则您需要开始读取视频帧。如果视频帧成功返回,将视频帧的大小调整为 (width, height)
,则将其设置为 frame
。
while cap.isOpened():
# Capture frame-by-frame
ret, frame = cap.read()
if ret:
ret_video, frame_video = img.read()
if ret_video:
# add image to frame
frame_video = cv2.resize(frame_video, (width, height))
frame[y:y + width, x:x + height] = frame_video
确保在执行后关闭 img
变量。
img.release()
cap.release()
cv2.destroyAllWindows()
请将 img
变量更改为有意义的值。比如将 img
变量重命名为 video_capture
,将 cap
重命名为 webcam_capture
。
当视频停止时,网络摄像头就会堆叠。但我想继续不定式。和视频应该重新开始。但是视频不是从开始开始的。网络摄像头冻结
更新
此问题已在 Playback loop option in OpenCV videos
如果你看答案,问题是通过计算视频帧数来解决的。当与捕获帧计数 (CAP_PROP_FRAME_COUNT
) 相等的视频帧设置为计数器且 CAP_PROP_FRAME_COUNT
设置为 0 时。
首先初始化帧计数器。
video_frame_counter = 0
当网络摄像头打开时,获取框架。如果帧返回,则将计数器加 1。
while cap.isOpened():
# Capture frame-by-frame
ret, frame = cap.read()
if ret:
ret_video, frame_video = img.read()
video_frame_counter += 1
如果计数器等于捕获类帧计数,则将两个变量都初始化为 0。
if video_frame_counter == img.get(cv2.CAP_PROP_FRAME_COUNT):
video_frame_counter = 0
img.set(cv2.CAP_PROP_POS_FRAMES, 0)
代码:
from os.path import sep
import cv2 as cv2
# load the overlay image. size should be smaller than video frame size
# img = cv2.VideoCapture('photos' + sep + 'Baslksz-3.mp4')
video_name = 'photos' + sep + 'Baslksz-3.mp4'
img = cv2.VideoCapture(video_name)
# Get Image dimensions
img.set(cv2.CAP_PROP_FRAME_WIDTH, 150) # float `width`
img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)
width = 150
height = 150
# Start Capture
cap = cv2.VideoCapture(0)
# cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 30)
# frame_vid = img.read()
# Decide X,Y location of overlay image inside video frame.
# following should be valid:
# * image dimensions must be smaller than frame dimensions
# * x+img_width <= frame_width
# * y+img_height <= frame_height
# otherwise you can resize image as part of your code if required
x = 50
y = 50
video_frame_counter = 0
while cap.isOpened():
# Capture frame-by-frame
ret, frame = cap.read()
if ret:
ret_video, frame_video = img.read()
video_frame_counter += 1
if video_frame_counter == img.get(cv2.CAP_PROP_FRAME_COUNT):
video_frame_counter = 0
img.set(cv2.CAP_PROP_POS_FRAMES, 0)
if ret_video:
# add image to frame
frame_video = cv2.resize(frame_video, (width, height))
frame[y:y + width, x:x + height] = frame_video
'''
tr = 0.3 # transparency between 0-1, show camera if 0
frame = ((1-tr) * frame.astype(np.float) + tr * frame_vid.astype(np.float)).astype(np.uint8)
'''
# Display the resulting frame
cv2.imshow('frame', frame)
# Exit if ESC key is pressed
if cv2.waitKey(1) & 0xFF == 27:
break
img.release()
cap.release()
cv2.destroyAllWindows()