In my application, I have one function which streams opencv video. During video streaming, if there is an event, then one thread supposed to start which is having time.sleep().
I have tried using the below-mentioned code. The problem is it is only displaying one frame and then the video stream terminates. What am I doing wrong? I also do not have the liberty to use 'While True' loop for the video streaming.
import threading
import time
import numpy as np
import cv2
# --- functions ---
def print_hello():
print("Hello")
time.sleep(3)
print("World")
# --- loop ---
cap = cv2.VideoCapture(0)
def show_frame():
global t
t = None
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
key = cv2.waitKey(1) & 0xFF
if key == ord('t'):
if t is None or not t.is_alive():
t = threading.Thread(target=print_hello)
t.start()
else:
print('previous thread is still running')
# --- after loop ---
if __name__ == '__main__':
show_frame()
if t is not None:
t.join()
cap.release()
cv2.destroyAllWindows()
Related
I want to run some mp4 videos inside a process but only camera feed works. The software gets stuck with no error message. I already tried both and I found this doesn't run. The print is where the code gets stuck.
import cv2
import multiprocessing
dispW=640
dispH=480
# Camera inputs
cap=cv2.VideoCapture('/home/kc/Downloads/darknet/1.mp4')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, dispW)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, dispH)
#cv2.namedWindow("Window")
def c1():
global cap
while True:
print('here')
success, img = cap.read()
#ret, frame1 = cap1.read()
#frame2 = numpy.hstack((frame,frame1))
print('here')
cv2.imshow("Window2", img)
#This breaks on 'q' key
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
tCap1 = multiprocessing.Process(target=c1)
tCap1.start()
this runs.
import cv2
import multiprocessing
dispW=640
dispH=480
# Camera inputs
cap=cv2.VideoCapture('/dev/video0')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, dispW)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, dispH)
#cv2.namedWindow("Window")
def c1():
global cap
while True:
success, img = cap.read()
#ret, frame1 = cap1.read()
#frame2 = numpy.hstack((frame,frame1))
print('here')
cv2.imshow("Window2", img)
#This breaks on 'q' key
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
tCap1 = multiprocessing.Process(target=c1)
tCap1.start()
I need an example of mp4 file run in a multiprocessing way.
Here's a minimal working example with optional FPS control. If you need to extract frames from your process back to the main program, you can use multiprocessing.Queue() to transfer frames since multiprocesses have an independent memory stack.
import multiprocessing as mp
import cv2, time
def capture_frames():
src = 'test.mp4'
capture = cv2.VideoCapture(src)
capture.set(cv2.CAP_PROP_BUFFERSIZE, 2)
# FPS = 1/X, X = desired FPS
FPS = 1/120
FPS_MS = int(FPS * 1000)
while True:
# Ensure camera is connected
if capture.isOpened():
(status, frame) = capture.read()
# Ensure valid frame
if status:
cv2.imshow('frame', frame)
else:
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(FPS)
capture.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
print('Starting video stream')
capture_process = mp.Process(target=capture_frames, args=())
capture_process.start()
Related camera/IP/RTSP/streaming, FPS, video, threading, and multiprocessing posts
Python OpenCV streaming from camera - multithreading, timestamps
Video Streaming from IP Camera in Python Using OpenCV cv2.VideoCapture
How to capture multiple camera streams with OpenCV?
OpenCV real time streaming video capture is slow. How to drop frames or get synced with real time?
Storing RTSP stream as video file with OpenCV VideoWriter
OpenCV video saving
Python OpenCV multiprocessing cv2.VideoCapture mp4
i am trying to stream a live vedio from cctv camera using open cv but vedio frame is showing and closing immediately. kindly help me out
import cv2
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
kernel=None
# This is a test video
cap = cv2.VideoCapture('rtsp://192.168.18.2277:554/user=admin_password=_channel=4_stream=0.sdp?real_stream.sdp')
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
# This function will return a boolean variable telling if someone was present or not, it will also draw boxes if it
# finds someone
ret = cap.set(3, 200)
ret = cap.set(4, 300)
cv2.imshow('frame', frame)
# Calculate the Average FPS
frame_counter += 1
fps = (frame_counter / (time.time() - start_time))
# Exit if q is pressed.
if cv2.waitKey(30) == ord('q'):
break
# Release Capture and destroy windows
cap.release()
cv2.destroyAllWindows()
Instead of using a if and else you can just write cv2.waitKey(1) at the end of your while loop. Hope that fixes the problem
Remove the if not ret: break statement and your code should work properly
I see 3 points to be changed above:
you have not imported time library but you have called the current time function in your algorithm.
start_time is specified but what will be the start time isn't. If it is the time that the program is executed then please define it.
Also you have to first define what is Frame_counter, and cannot directly increment it by 1.
import cv2
#import time function
import time
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
kernel=None
cap = cv2.VideoCapture(0)
#define start_time
start_time = time.time()
#frame counter value
frame_counter = 1
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
ret = cap.set(3, 200)
ret = cap.set(4, 300)
cv2.imshow('frame', frame)
frame_counter += 1
fps = (frame_counter / (time.time() - start_time))
if cv2.waitKey(30) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Please excuse if there are any mistakes, I am also a beginner.
I'm simply trying to get the image of my webcam in python with OpenCV 4.2.0 (on Spyder - python 3.7 running on windows 10). I just copy-pasted the code of the OpenCV documentation (see below) and most of the time it prints: "Can't receive frame (stream end?). Exiting ..."
So I know the error comes from: ret, frame = cap.read(). But I don't know how to fix this.
Sometimes it prints: "Cannot open camera" and then it exits the Spyder Console and starts a new one
And sometimes it just works great...
Can anyone help?
Here is my code:
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# Our operations on the frame come here
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Display the resulting frame
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
Added the last line to close the window
I had a similar issue (now for a while). I run Linux, not Windows. I read video feeds from multiple IP cameras, not just one webcam. But I believe the solution would be the same. In my opinion, it looks as if the feed, or OpenCv stops supplying frames. So I simply recreate cap, test ret, and move on. This will create a endless loop, it will never stop. In my scenario this correct. I want to real all frames, all the time.
It will look something like:
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('rtsp://1.2.3.4:554//Streaming/Channels/1')
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
while ret == False:
print("Can't receive frame. Retrying ...")
cap.release()
cap = cv.VideoCapture('rtsp://1.2.3.4:554//Streaming/Channels/1')
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
print('frame')
# Display the resulting frame
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)# In place of zero we gonna use path of the video file.
while cap.isOpened():
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if ret:
# Our operations on the frame come here
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Display the resulting frame
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
else:
print("camer not streaming")
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
I have written a code to enable capturing images from webcam feed using OpenCV. However there is an input delay whenever I press the key to capture my frame. There is no delay when I use it to quit, but there a significant delay when I use capture. I measured this by printing a statement inside both the cases, on pressing c the statement takes a delay before printing. The problem seems to me something like...the camera resources are being used and not freed up in time for the next key press or something like that....but not sure.
import cv2 as cv
import numpy as np
import glob
import matplotlib.pyplot as plt
cap = cv.VideoCapture(1)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
if cv.waitKey(1) & 0xFF == ord('q'):
print('helloq')
break
elif cv.waitKey(1) & 0xFF == ord('c'):
print('hello{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
I am using an external web camera and
cv2.__version__ = 3.4.2`
Solved your issue, it seems like its caused by your key check.
You should not call waitKey(1) more than once. It causes lag.
Try this solution:
cap = cv.VideoCapture(0)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
key = cv.waitKey(1)
if key==ord('c'):
print('img{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
print("Succesfully saved!")
if key==ord('q'):
print('Closing cam...')
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
I am trying to take 2 photos, but as result I see first one two times. I have tried using two variables for frames and saving them as file. How can I fix the problem?
#!/usr/bin/python
import cv2
import time
cap = cv2.VideoCapture(0)
time.sleep(0.25)
ret1, t1 = cap.read()
print 'ret1:', ret1
cv2.imshow('test',t1)
cv2.waitKey(0)
ret1, t1 = cap.read()
print 'ret1:', ret1
cv2.imshow('test1',t1)
cap.release()
while True:
time.sleep(1)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()