Opencv-在网络摄像头上叠加视频

Opencv-Overlay a Video on Webcam

伙计们,我在将视频叠加到网络摄像头时遇到了问题。我可以毫无问题或错误地打开网络摄像头,但没有显示我的视频。我正在尝试以特定的 x-y 播放我的视频 coordinates.I 从另一个 Whosebug 问题中获取我的大部分代码,但我找不到它知道所以我不能在这里提及它。

有人可以帮我解决这个问题吗?为什么我的视频没有在我的网络摄像头中播放? 我有以下代码:

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()

让我开始一步步分析代码。

  • 第 1 步
img = cv2.VideoCapture('photos' + sep + 'Baslksz-3.mp4')

上面的代码看起来不错,但如果你给出一个字符串名称会更好

video_name = 'photos' + sep + 'Baslksz-3.mp4'
img = cv2.VideoCapture(video_name)
  • 第 2 步
# Get Image dimensions
width = img.set(cv2.CAP_PROP_FRAME_WIDTH, 150)  # float `width`
height = img.set(cv2.CAP_PROP_FRAME_HEIGHT, 150)

现在 widthheight 变量是什么?

# 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

您似乎想将 widthheight 设置为维度 (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
  • 第 3 步
# 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 变量两次?

  • 第 4 步
frame_vid = img.read()

为什么要初始化frame_vid你在代码的任何地方都没有用到?

  • 第 5 步
while (True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    frame[y:y + width, x:x + height] = img

以上代码没有任何意义,只要您的网络摄像头打开,您就想显示您的视频。您也没有检查当前网络摄像头帧是否 returns。您还将 VideoCapture 变量设置为数组?

while cap.isOpened():
    # Capture frame-by-frame
    ret, frame = cap.read()

现在你正在取帧,只要你的摄像头是打开的,那么你需要检查摄像头是否有帧returns。如果网络摄像头帧 returns 那么您需要开始读取视频帧。如果视频帧 returns 成功将视频帧大小调整为 (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
  • 第 6 步

确保在执行后关闭 img 变量。

img.release()
cap.release()
cv2.destroyAllWindows()

请将 img 变量更改为有意义的值。就像将 img 变量重命名为 video_capture 并将 cap 重命名为 webcam_capture.

When video stops then webcam stacks. But I want to continue infinitive. and video should start again. But video does not starts from beggining.and webcam freezes

更新


Playback loop option in OpenCV videos

中提到了这个问题

看了答案,通过计算视频帧数解决了问题。当视频帧等于捕获帧计数(CAP_PROP_FRAME_COUNT)设置为计数器并且CAP_PROP_FRAME_COUNT为0.

首先初始化帧计数器。

video_frame_counter = 0

当网络摄像头打开时,获取框架。如果帧 returns,则将计数器加 1。

while cap.isOpened():
    # Capture frame-by-frame
    ret, frame = cap.read()

    if ret:
        ret_video, frame_video = img.read()
        video_frame_counter += 1

如果计数器等于捕获的class帧计数,则将两个变量都初始化为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()