0

Guys I am having problem on overlaying my video to webcam. I can open webcam without any issues or errors but my video is not being showed. I am trying to play my video in specific x-y coordinates.I take most of my code from an other stackoverflow question but I cannot find it know so that I cannot mention it here.

So can someone help me to solve this? Why my video is not being played in my webcam? I have following code:

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()
  • 2
    Poor choice of variable name. `frame[ y:y+width , x:x+height ] = img` ... the `img` is **not** an image, but an instance of `cv>VideoCapture`, so that statement doesn't make any sense. – Dan Mašek Feb 06 '21 at 11:43
  • 2
    In addition, `cv.VideoCapture.set` returns a boolean, so `width` and `height` aren't what they say either, making the above mentioned statement even more nonsensical. Furthermore, setting the width and height properties on `VideoCapture` reading a file has no effect at all, it's only useful to change the resolution of a camera. – Dan Mašek Feb 06 '21 at 11:47
  • Thanks for replying, I got the answer. Thanks for your help – Ö. ALP EREN GÜL Feb 07 '21 at 13:47
  • *Can you please loook at this question:https://stackoverflow.com/questions/66088152/opencv-change-transparent-videos-if-face-detection-is-true I need your help – Ö. ALP EREN GÜL Feb 07 '21 at 13:48

1 Answers1

2

Let me start analyzing the code step-by-step.

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

The above code look fine, but it would be better if you give as a string name

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

Now what are width and height variables?

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

Result is:

False
False

It seems you want to set width and height to the dimension (150, 150). It would be better if you initialize them separately

# 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
  • Step #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)

Why do you initialize cap variable two-times?

  • Step #4
frame_vid = img.read()

Why do you initialize frame_vid you did not use anywhere in the code?

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

The above code is not making any sense, you want to display your video as long as your webcam open. You also did not check whether the current webcam frame returns or not. You also set VideoCapture variable to the array?

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

Now you are getting frames, as long as your webcam is open, then you need to check whether the webcam frame returns. If the webcam frame returns then you need to start reading the video frames. If the video frame returns successfully resize the video frame to (width, height) then set it to the 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
  • Step #6

Make sure close img variable after the execution.

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

Please change img variable to something that makes sense. Like rename the img variable to video_capture and cap to the 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

Update


This issue was mentioned in the Playback loop option in OpenCV videos

If you look at the answer, the problem was solved by counting the video frames. When video frames equal to the capture frame count (CAP_PROP_FRAME_COUNT) set to counter and CAP_PROP_FRAME_COUNT to 0.

First initialize the frame counter.

video_frame_counter = 0

and when webcam opens, get the frame. If frame returns, increase the counter by 1.

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

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

If counter equals to the capture class frame count, then initialize both variable to 0.

if video_frame_counter == img.get(cv2.CAP_PROP_FRAME_COUNT):
    video_frame_counter = 0
    img.set(cv2.CAP_PROP_POS_FRAMES, 0)

Code:


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()
Ahmet
  • 7,527
  • 3
  • 23
  • 47
  • Thanks for answering, your reply make everything much clear. Really I am gratitude to you.... – Ö. ALP EREN GÜL Feb 06 '21 at 15:32
  • Ok but still make sure you won't left any unused variable in the code. Make sure comment them, if you are planning to use in the future – Ahmet Feb 06 '21 at 18:38
  • Can I ask something? I think there is a problem in our code. 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. – Ö. ALP EREN GÜL Feb 06 '21 at 18:48
  • I've updated my code based on the problem. If you want to read the explanation, please see Update part. – Ahmet Feb 06 '21 at 19:16
  • Yes thanks for your answers, I am new to opencv and trying to learning. – Ö. ALP EREN GÜL Feb 07 '21 at 13:50
  • Sir this is my last question : https://stackoverflow.com/questions/66105035/opencv-webcam-stops-when-i-try-to-overlaying-transparent-videos-on-webcam I hope you will look at it.... Otherwise dont worry – Ö. ALP EREN GÜL Feb 08 '21 at 16:00
  • The link is not opening, did you delete the question? – Ahmet Feb 08 '21 at 19:12
  • yes, I solved it by searching and getting help from facebook forum. Thanks for everything Ahx – Ö. ALP EREN GÜL Feb 09 '21 at 06:01