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()
Answer from Ahmet on Stack OverflowPaste video on the top of the image - Python - OpenCV
How to Blend / Add / Insert an Image to Video and Real Time Live Stream via Webcam to Tensorflow bbox coordinates to spawn my image around that rectangle with OpenCV Python - Python - OpenCV
python - Overlay transparent video to camera feed OpenCV - Stack Overflow
How I Can insert images on Captured video in Python - Stack Overflow
If you take a sample of random frames as elements of an array, and calculate the FFT, all the semi-transparent boxes will have a very high signal, and the rest of the pixels would behave as noise, so noise remotion will filter away the semi-transparent boxes. You can add the result of your other methods as additional frames for the fft
You are trying to find something that does not changes on the entire video, so do not use consecutive frames, or if you are forced to use consecutive frames, shuffle them randomly.
To gain speed, you may only take only one color channel from each frame, and pick the color channel randomly. That way the colors becomes noise, and cancel each other.
If the FFT is too expensive, just averaging random frames should filter the noise.
Ok here is first step, you can make Canny from that image, from canny you can make countours:
import cv2
import random as rng
image = cv2.imread("c:\stackoverflow\interface.png")
edges = cv2.Canny(image, 100, 240)
contoursext, hierarchy = cv2.findContours(
edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#cv2.RETR_EXTERNAL would work better if the image would not be framed.
for i in range(len(contoursext)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv2.drawContours(image, contoursext, i, color, 1, cv2.LINE_8, hierarchy, 0)
# Show in a window
cv2.imshow("Canny", edges)
cv2.imshow("Contour", image)
cv2.waitKey(0)

Then you can test if the contour or combination of 2 contours is rectangles for example...wich would probably detect most of the rectangle overlays...
Or Also you can try to detect canny lines if they are similar to rectangles.
