Opencv-在网络摄像头上覆盖视频

时间:2021-02-06 11:14:31

标签: python opencv opencv-python

伙计们,我在将视频叠加到网络摄像头时遇到问题。我可以打开网络摄像头而没有任何问题或错误,但我的视频没有显示。我正在尝试在特定的 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()

1 个答案:

答案 0 :(得分:2)

让我开始逐步分析代码。

  • 第 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

上面的代码没有任何意义,只要您的网络摄像头打开,您就想显示您的视频。您也没有检查当前网络摄像头框架是否返回。您还将 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
  • 第 6 步

确保在执行后关闭 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()