I would like to access my webcam from Python.
I tried using the VideoCapture extension (tutorial), but that didn't work very well for me, I had to work around some problems such as it's a bit slow with resolutions >320x230, and sometimes it returns None for no apparent reason.
Is there a better way to access my webcam from Python?
OpenCV has support for getting data from a webcam, and it comes with Python wrappers by default, you also need to install numpy for the OpenCV Python extension (called cv2) to work.
As of 2019, you can install both of these libraries with pip:
pip install numpy
pip install opencv-python
More information on using OpenCV with Python.
An example copied from Displaying webcam feed using opencv and python:
import cv2
cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)
if vc.isOpened(): # try to get the first frame
rval, frame = vc.read()
else:
rval = False
while rval:
cv2.imshow("preview", frame)
rval, frame = vc.read()
key = cv2.waitKey(20)
if key == 27: # exit on ESC
break
vc.release()
cv2.destroyWindow("preview")
gstreamer can handle webcam input. If I remeber well, there are python bindings for it!
Related
Code:
from imutils.video import VideoStream
import cv2
# Read rtsp stream
rtsp = u"rtsp://admin:admin#10.64.1.31:554/1/h264major"
#vs = VideoStream(src=0).start() # for capturing from webcam
vs = VideoStream(src=rtsp).start()
while True:
frame = vs.read()
# show the output frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()
I have faced the same problem when using opencv's VideoCapture [ cap.isOpened() returns False ]
The standalone executable works fine when capturing from webcam in both cases i.e. cv2.VideoCapture(0) or VideoStream(src=0).start()
The rtsp stream capture works fine in both cases when the script is run in python i.e. without turning it into a standalone executable.
The rtsp stream was tested on VLC player and works fine.
I am using Python 3.6.2 | OpenCV 3.2.0 | Windows
Could this be due to utf-8 etc encoding issues of the RTSP link? Any other alternatives?
Solved: Included opencv_ffmpeg320_64.dll next to my executable.
Included opencv_ffmpeg320_64.dll next to my executable.
Alternatively, copy that dll file to the DLLs folder in python directory
I'm trying to read a video file in opencv (python 2.7), and I just copied the example in the opencv tutorial, but nothing happens:
import numpy as np
import cv2
cap = cv2.VideoCapture('input.mp4')
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
The function cap.isOpened always returns FALSE.I have already tried to use absolute path in the argument of VideoCapture, but I still get the same result. What am I getting wrong?
Maybe your OpenCV version is not properly installed. You can check your build infos with print cv2.getBuildInformation() if there is any weird components.
I would suggest to rebuild it, or install it via Anaconda to be sure not to miss any package.
You need to define video location or move the video where python is installed
Keep the full path of the video file.
For example :-
cap = cv2.VideoCapture("D:\\Video Folder\\input.mp4")
I believe this would solve this issue.
I have a simple piece of code, written in Python (version 2.7.11) designed to do things to a video file as follows:
import cv2
cap = cv2.VideoCapture('MyVideo.mov')
print(cap)
print(cap.isOpened())
while(cap.isOpened()):
#Do some stuff
The result of print(cap) is a 8 digit hex number, so I don't know if that means that the video has been found.
However, the print statement for cap.isOpened() returns False. I have tried several fixes, but none of them worked. Any help or insight would be very helpful.
Things to note/things I have tried
I am running Windows 8.1, Python 2.7.11 and OpenCV 3.1.0
The location of the video file is in the same directory as the Python script
I have the following directories appended to my PATH variable:
C:\Users\MyName\OpenCV3\opencv\build\x64\vc14\bin;
C:\Users\MyName\OpenCV3\opencv\sources\3rdparty\ffmpeg;
C:\Python27\;
C:\Python27\Scripts
I have checked that I have opencv_ffmpeg.dll in the OpenCV vc14 bin directory
I have checked that said dll file is titled opencv_ffmpeg310_64.dll
I have tried redownloading said dll file, and renaming it to include the version of OpenCV and the fact that my system is a 64-bit one
I have tried placing the dll file in the Python27 directory
The code above works on Mac, but not on Windows (tried the code on 2 different Macs and it worked, tried it on 2 different Windows machines and it returned false both times)
It is most likely that if you are using windows, files are in a \Users or other \<something> directory. The \ is seen as a unicode escape by the python interpreter and whatever follows it is probably an invalid escape. try typing r'<file path>' to cause the path to be read as raw text and have the unicode escapes ignored.
Try adding:
if(not cap.isOpened()):
cap.open(r'<file_path>')
And if the problem is the file path, it will probably cause an error. Alternatively, you could just use a loop like this:
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
#if frame can't be read
if ret==False:
print('end of input or incompatible video file')
break
cv2.imshow('frame',frame)
#if esc key pressed
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
cap.release()
Since your code shows no issues on Mac, try using other file extensions (eg. mp4 or wmv) on your Windows system, for testing. If your video is loaded then, that means OpenCV is correctly configured on your Windows, but apparently there is no driver to play .mov files
try using this :
cam=cv2.VideoCapture('MyVideo.mov')
while(True):
ret, img = cam.read()
print ("frame", img)
if cv2.waitKey(100) & 0xFF == ord('q'):
break
cam.release()
cv2.destroyAllWindows()
I have recently set up a Raspberry Pi camera and am streaming the frames over RTSP. While it may not be completely necessary, here is the command I am using the broadcast the video:
raspivid -o - -t 0 -w 1280 -h 800 |cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/output.h264}' :demux=h264
This streams the video perfectly.
What I would now like to do is parse this stream with Python and read each frame individually. I would like to do some motion detection for surveillance purposes.
I am completely lost on where to start on this task. Can anyone point me to a good tutorial? If this is not achievable via Python, what tools/languages can I use to accomplish this?
Using the same method listed by "depu" worked perfectly for me.
I just replaced "video file" with "RTSP URL" of actual camera.
Example below worked on AXIS IP Camera.
(This was not working for a while in previous versions of OpenCV)
Works on OpenCV 3.4.1 Windows 10)
import cv2
cap = cv2.VideoCapture("rtsp://root:pass#192.168.0.91:554/axis-media/media.amp")
while(cap.isOpened()):
ret, frame = cap.read()
cv2.imshow('frame', frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Bit of a hacky solution, but you can use the VLC python bindings (you can install it with pip install python-vlc) and play the stream:
import vlc
player=vlc.MediaPlayer('rtsp://:8554/output.h264')
player.play()
Then take a snapshot every second or so:
while 1:
time.sleep(1)
player.video_take_snapshot(0, '.snapshot.tmp.png', 0, 0)
And then you can use SimpleCV or something for processing (just load the image file '.snapshot.tmp.png' into your processing library).
use opencv
video=cv2.VideoCapture("rtsp url")
and then you can capture framse. read openCV documentation visit: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html
Depending on the stream type, you can probably take a look at this project for some ideas.
https://code.google.com/p/python-mjpeg-over-rtsp-client/
If you want to be mega-pro, you could use something like http://opencv.org/ (Python modules available I believe) for handling the motion detection.
Here is yet one more option.
It's much more complicated than the other answers.
But this way, with just one connection to the camera, you could "fork" the same stream simultaneously to several multiprocesses, to the screen, recast it into multicast, write it to disk, etc.
Of course, just in the case you would need something like that (otherwise you'd prefer the earlier answers)
Let's create two independent python programs:
Server program (rtsp connection, decoding) server.py
Client program (reads frames from shared memory) client.py
Server must be started before the client, i.e.
python3 server.py
And then in another terminal:
python3 client.py
Here is the code:
(1) server.py
import time
from valkka.core import *
# YUV => RGB interpolation to the small size is done each 1000 milliseconds and passed on to the shmem ringbuffer
image_interval=1000
# define rgb image dimensions
width =1920//4
height =1080//4
# posix shared memory: identification tag and size of the ring buffer
shmem_name ="cam_example"
shmem_buffers =10
shmem_filter =RGBShmemFrameFilter(shmem_name, shmem_buffers, width, height)
sws_filter =SwScaleFrameFilter("sws_filter", width, height, shmem_filter)
interval_filter =TimeIntervalFrameFilter("interval_filter", image_interval, sws_filter)
avthread =AVThread("avthread",interval_filter)
av_in_filter =avthread.getFrameFilter()
livethread =LiveThread("livethread")
ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://user:password#192.168.x.x", 1, av_in_filter)
avthread.startCall()
livethread.startCall()
avthread.decodingOnCall()
livethread.registerStreamCall(ctx)
livethread.playStreamCall(ctx)
# all those threads are written in cpp and they are running in the
# background. Sleep for 20 seconds - or do something else while
# the cpp threads are running and streaming video
time.sleep(20)
# stop threads
livethread.stopCall()
avthread.stopCall()
print("bye")
(2) client.py
import cv2
from valkka.api2 import ShmemRGBClient
width =1920//4
height =1080//4
# This identifies posix shared memory - must be same as in the server side
shmem_name ="cam_example"
# Size of the shmem ringbuffer - must be same as in the server side
shmem_buffers =10
client=ShmemRGBClient(
name =shmem_name,
n_ringbuffer =shmem_buffers,
width =width,
height =height,
mstimeout =1000, # client timeouts if nothing has been received in 1000 milliseconds
verbose =False
)
while True:
index, isize = client.pull()
if (index==None):
print("timeout")
else:
data =client.shmem_list[index][0:isize]
img =data.reshape((height,width,3))
img =cv2.GaussianBlur(img, (21, 21), 0)
cv2.imshow("valkka_opencv_demo",img)
cv2.waitKey(1)
If you got interested, check out some more in https://elsampsa.github.io/valkka-examples/
Hi reading frames from video can be achieved using python and OpenCV . Below is the sample code. Works fine with python and opencv2 version.
import cv2
import os
#Below code will capture the video frames and will sve it a folder (in current working directory)
dirname = 'myfolder'
#video path
cap = cv2.VideoCapture("your rtsp url")
count = 0
while(cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
else:
cv2.imshow('frame', frame)
#The received "frame" will be saved. Or you can manipulate "frame" as per your needs.
name = "rec_frame"+str(count)+".jpg"
cv2.imwrite(os.path.join(dirname,name), frame)
count += 1
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Use in this
cv2.VideoCapture("rtsp://username:password#IPAddress:PortNO(rest of the link after the IPAdress)").
I'm new to python and Opencv and I tried to put in the following code to save an image to my computer from my webcam:
import cv
if __name__=='__main__':
pCapturedImage = cv.CaptureFromCAM(1)
rospy.sleep(0.5)
pSaveImg=cv.QueryFrame(pCapturedImage)
cv.SaveImage("test.jpg", pSaveImg)
But when I try to open it,
I find that the jpeg is empty.
Could someone please help?
Also, I tried a program to show what my webcam is seeing:
import cv
if __name__=='__main__':
cv.NamedWindow("camera",1)
capture=cv.CaptureFromCAM(0)
while True:
img=cv.QueryFrame(capture)
cv.ShowImage("camera", img)
if cv.WaitKey(10)==27:
break
cv.DestroyedWindow("camera")
But when I run it, I get an application that just shows me a gray screen.
Could someone help with this too?
Thanks.
Have you tried the demo programs? They show how to use the webcam among many other things.
For the first problem, I am not familiar with using cameras in opencv, but I got it to work by opening the capture (capture.open(device_id) in the code below)
Here is a working python sample (I use the newer c++ interface: imread, imwrite, VideoCapture, etc... which you can find in the OpenCV docs listed as "cv2" when it is available for python.):
import cv2
capture = cv2.VideoCapture() # this is the newer c++ interface
capture.open(0) # Use your device id; I think this is what you are missing.
image = capture.read()[1]
cv2.imwrite("test.jpg", image)
I got your second sample also working just by using open on the capture object:
import cv2
cv2.namedWindow("camera", 1) # this is where you will put the video images
capture = cv2.VideoCapture()
capture.open(0) # again, use your own device id
while True:
img = capture.read()[1]
cv2.imshow("camera", img)
if cv2.waitKey(10) == 27: # waiting for the esc key
break
cv2.destroyWindow("camera")