0
votes

I want to overlay webcam captured video on another video in live. So I have tried the above code,but it's too slow.

Should I shift to another language or lib or something?

Any suggestion or help will be appreciated.

import numpy as np
from cv2 import cv2


def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
     # initialize the dimensions of the image to be resized and
     # grab the image size
     dim = None
     (h, w) = image.shape[:2]

     # if both the width and height are None, then return the
     # original image
     if width is None and height is None:
          return image

     # check to see if the width is None
    if width is None:
         # calculate the ratio of the height and construct the
         # dimensions
         r = height / float(h)
         dim = (int(w * r), height)

         # otherwise, the height is None
    else:
         # calculate the ratio of the width and construct the
         # dimensions
         r = width / float(w)
         dim = (width, int(h * r))

    # resize the image
    resized = cv2.resize(image, dim, interpolation = inter)

    # return the resized image
    return resized



cap2 = cv2.VideoCapture('http://192.168.43.1:8080/video')
cap = cv2.VideoCapture('test.mp4')

# Define the codec and create VideoWriter object 
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('sample3.mp4',fourcc,30, (640,480))


# watermark = logo

# cv2.imshow("watermark",watermark)

while(cap.isOpened()):
    ret, frame = cap.read()
    frame = cv2.cvtColor(frame,cv2.COLOR_BGR2BGRA)

    ret2 ,frame2 = cap2.read()
    frame2 = cv2.cvtColor(frame2,cv2.COLOR_BGR2BGRA)

    watermark = image_resize(frame2,height=177)

    if ret==True:
        frame_h, frame_w, frame_c = frame.shape
        overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')
        overlay[543:543+177,1044:1044+236] = watermark
        cv2.addWeighted(frame, 0.25, overlay, 1.0, 0, frame)
       
        frame = cv2.cvtColor(frame,cv2.COLOR_BGRA2BGR)

        out.write(frame) 

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

Requirement is to overlay webcam live video on another video at bottom smoothly.

Thanks.

1
Have you identified the bottleneck in your pipeline? - stateMachine
@eldesgraciado Result frame rate is very low(1 or 2 fps), but without overlaying it runs as quick as 30 fps. - user13441281
the given answer solves your original question. you have since removed the code that was slow and replaced it with the answer. that makes your question impossible to understand. besides, the code in your current version of the question is no longer slow. - Christoph Rackwitz

1 Answers

2
votes

Basically, if you want it to be fast, you may not iterate over an image using a python cycle. You are trying to copy the scaled-down image into the empty overlay using 2 nested cycles and that's terribly slow. I do not understand the condition

             if watermark[i,j][3] != 0:

Also this part:

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

should be out of the cycle - they are all constants.

But most importantly instead of cycling over the image you can do:

offset[h_offset:h_offset+watermark_h,w_offset:w_offset+watermark_w] = watermark

After this, I am up from 9 fps to 28 fps.