I'm fighting with Chinese IP camera modules, one of them has chipset IMX322 and has 2MPX. I managed to connect to this camera (there was no doc. how to do it ) but url above seems to work :
rtsp://<local_ip>/user=admin&password=&channel=1&stream=0.sdp
I use standard python loop to get data, but there is some problem and I'm really not sure where, it can be problem with camera (wrong header) or library under Nvidia Jetson TX2 and Ubuntu 16.4.
#!/usr/bin/env python
import sys
from time import sleep
import numpy as np
import cv2
import time
cap = cv2.VideoCapture('rtsp://192.168.1.11/user=admin&password=&channel=0&stream=0.sdp?tpc')
while(True):
ret, frame = cap.read()
if ret:
cv2.imshow("Image", cv2.resize(frame,(800,600)))
else:
print('no video')
#cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
The problem is that I'm getting unexpected behavior of VideoCapture(), it takes about 2 seconds to generate output frame in imgShow, but before that I'm receiving errors in command line level 2,3 times.
Invalid UE golomb code
Invalid UE golomb code
During extraction of correct frames from camera errors are still showing with frequency 1,2 per second. I tried to find any useful information in google but it looks like 90% of post are related with C++ or FFMPEG.
Related
We have a videostream from camera with the help of NDI. How can we get it in OpenCV?
import cv2
cap = cv2.VideoCapture("tcp://192.168.1.69")
while cap.isOpened():
_, frame = cap.read()
# frame processing
We have tried the following variation of a string:
tcp://192.168.1.69
tcp://192.168.1.69:8080
http://192.168.1.69
http://192.168.1.69:8080
udp://192.168.1.69:8080
But we get an error every time. What is the correct string to use NDI stream?
A bit late and I'm sure you may have already come across the solution. You also failed to state the platform requirements. So the solution I have is currently Windows only at the moment.
The "NDI Virtual Input" driver allows an NDI network stream to be treated as a Webcam source. Thus you can just set the video capture source to the ID of the device. This requires the driver be installed on the client system
import cv2
cap = cv2.VideoCapture(1) # Could be any number, it's system specific, but it's u=usually 0, 1 etc.
while cap.isOpened():
_, frame = cap.read()
# frame processing
Have a look at PyNDI - I added some examples there to show you how to get NDI into openCV.
The SimpleSourceViewer is command line based, the GUIExample uses TKInter to give you an interface.
This has been keeping me busy for a good part of the afternoon and I haven't been able to get it to work but I feel like I'm really close.
I've got openCV set up which takes the videofeed from a webcam. To be able to access this video feed (with openCV overlay) I want to pipe the output of the openCV python script to a VLC stream. I managed to get the stream up and running and can connect to it. VLC resizes to the correct aspect ratio and resolution so it gets some correct data but the image I get is just Jitter;
python opencv.py | cvlc --demux=rawvideo --rawvid-fps=30 --rawvid-width=320 --rawvid-height=240 --rawvid-chroma=RV24 - --sout "#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}" &
The output of the script is a constant video feed sent to stdout as follows
from imutils.video import WebcamVideoStream
vs = WebcamVideoStream(src=0)
while True:
frame = vs.read()
sys.stdout.write(frame.tostring())
Above example is a dumbed down version of the script I'm using; Also as seen I'm making use of the imutils library; https://github.com/jrosebr1/imutils
If anyone could give me a nudge in the right direction I would appreciate it greatly. My guess is the stdout.write(frame.tostring()) is not what vlc expects but I haven't been able to figure it out myself.
The following works for me under Python 3
import numpy as np
import sys
import cv2
cap = cv2.VideoCapture(0)
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
sys.stdout.buffer.write(frame.tobytes())
else:
break
cap.release()
And the command line (my webcam has a different resolution, and I only display the result, but you did not have problems with that)
python opencv.py | vlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=640 --rawvid-height=480 --rawvid-chroma=RV24 - --sout "#display"
Of course this requires a conversion from BGR to RGB as the former is default in OpenCV.
This worked for me, though I am sending to RTSP stream and not using imutils library:
import numpy as np
import sys
import cv2
input_rtsp = "rtsp://10.10.10.9:8080"
cap = cv2.VideoCapture(input_rtsp)
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
sys.stdout.write(frame.tostring())
else:
break
cap.release()
Then in command line:
python opencv.py | cvlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=1280 --rawvid-height=720 --rawvid-chroma=RV24 - --sout "#transcode{vcodec=h264,vb=200,fps=25,width=1280,height=720}:rtp{dst=10.10.10.10,port=8081,sdp=rtsp://10.10.10.10:8081/test.sdp}"
Note that you do not need to convert opencv BGR to RGB.
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 am using the following code to access my webcam using openCV + python...
import cv
cv.NamedWindow('webcam_feed', cv.CV_WINDOW_AUTOSIZE)
cam = cv.CaptureFromCAM(-1)
I am then getting the following error in the console...
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
I was originally using,
cv.CaptureFromCAM(0)
to access the same and had the same issue and used -1 because it is suppose to pick up any webcam.
I also tested to see if Ubuntu recognizes the webcam and it does. I am using v4l2 for the webcam.
{EDIT}
I am using the following code to display a video feed, it seems to only be showing just one image the web cam captured instead of a continuous video feed...
import cv
cv.NamedWindow('webcam_feed', cv.CV_WINDOW_AUTOSIZE)
cam = cv.CaptureFromCAM(-1)
feed = cv.QueryFrame(cam)
cv.ShowImage("webcam_feed", feed)
cv.WaitKey(-1)
WOW, answered my own question in 15 after me posting this. I did some research and the reason for the web cam only grabbing one image is because of the...
cv.WaitKey(-1)
This doesn't allow the contents of the window to refresh. I set the number to 10...
cv.WaitKey(10)
and it worked beautifully. I also tried 100, but saw no difference. I only saw a difference when the number was 1000. I use 1 because seems that it runs the smoothest.
Here is the full code to display a web cam feed
import cv
cv.NamedWindow("webcam", 1)
cam = cv.CaptureFromCAM(-1)
While True:
feed = cv.QueryFrame(cam)
cv.ShowImage("webcam", feed)
cv.WaitKey(1)
I believe you need to put
frame = cv.QueryFrame(cam)
cv.ShowImage("Webcam Feed", frame)
in a loop to continuously update the image shown in the window. That is, the frame from cv.QueryFrame is a static image, not a continuous video.
If you want to be able to exit with a key press, test cv.WaitKey with a small timeout in the loop too.
For me, the command in root
xhost +
save my time, Note to close and open new terminal.
See you.
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")