cv2.VideoCapture(0, cv2.DSHOW) returns none - opencv

I'm trying to capture video from an in-build webcam on a laptop (or external USB camera) using opencv, specifically VideoCapture with the DSHOW argument.
I know there is a way to set the resolution and even FPS, however the DirectShow argument for the API returns none when I included it in the code.
For example;
# returns my webcam's stream, but all optional arguments are ignored
camera = cv2.VideoCapture(0)
camera = cv2.VideoCapture(0, cv2.CAP_V4L2)
# returns none and loops infinitely or errors out when *if im.any()*
camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
This is the code that follows after the above;
# should set resolution, settings are always ignored
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
while(True):
retval, im = camera.read()
if im.any(): # errors out when image is none
cv2.imshow("image", im)
k = cv2.waitKey(33)
if k==27: # Esc key press
print('Resolution: {0}x and {1}y'.format(im.shape[1],im.shape[0]))
print('FPS: {0}'.format(camera.get(cv2.CAP_PROP_FPS)))
break
camera.release()
cv2.destroyAllWindows()
Is the DSHOW the correct API to use and is it the only API to use that can change resolution and FPS of a camera stream using opencv? Or is there something else I'm doing incorrectly?
More details about the system.
Ubuntu 18.04.6
python 3.9.5
opencv-python 4.5.2.52
Thank you in advance for the help!
Regards, Tiz

DSHOW (and MSMF) are windows only.
on linux, use V4L, FFMPEG or GSTREAMER
also, please check the return val of capture.set(),
not all properties/values will be supported on any given machine

Related

Change video stream resolution in YoloV4 demo

Here's what shows when loading the live stream demo for Yolov4:
Webcam index: 2
[ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (935) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1
Video stream: 2304 x 1536
Objects:
Then it starts finding objects with 2 fps.
How do I change the video stream resolution to 1080p or 720p? The frame rate is very slow and this appears to be the fix.
Can't find it within the makefile or cfg folder. Any thoughts? Is this an opencv problem?
Thanks!
cfg settings:
[net]
batch=64
subdivisions=8
# Training
#width=512
#height=512
width=320
height=320
channels=3
momentum=0.949
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
learning_rate=0.0013
burn_in=1000
max_batches = 500500
policy=steps
steps=400000,450000
scales=.1,.1
I tried with the built-in camera and connected my phone(IP) and got 1080 on both with smooth results. I didn't find anywhere to change the webcam settings which are stuck on 2304x1536. Where would camera settings be located?
After searching around for a solution to this issue myself I finally found it!
In the darknet/src/ folder is a file named "image_opencv.cpp". At lines 597 and 598 you will find the following 2 commented commands:
//cap->set(CV_CAP_PROP_FRAME_WIDTH, 1280);
&
//cap->set(CV_CAP_PROP_FRAME_HEIGHT, 960);
After trying out these commands a lot more errors showed up, this is due to yolov4 (and my install) using OpenCV 4.1.1. Which has a different syntax. Your resolution should change to 1920x1080 if you replace the two aforementioned commands with these:
cap->set(cv::CAP_PROP_FRAME_WIDTH, 1920);
cap->set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
Notice that the comment slashes have been removed as to activate the commands.

OpenCV 4.1.1.26 reports 90000.0 fps for a 25fps RTSP stream

I have an RTP/RTSP stream that's running at 25fps, as verified by ffprobe -i <URI>. Also, VLC plays back the RTSP stream at a real-time rate, but doesn't show me the FPS in the Media Information window.
However, when I use OpenCV 4.1.1.26 to retrieve the input stream's frame rate, it is giving me a response of 90000.0.
Question: How can I use OpenCV to probe for the correct frame rate of the RTSP stream? What would cause it to report 90000.0 instead of 25?
Here's my Python function to retrieve the frame rate:
import cv2
vid : cv2.VideoCapture = cv2.VideoCapture('rtsp://192.168.1.10/cam1/mpeg4')
def get_framerate(video: cv2.VideoCapture):
fps = video.get(cv2.CAP_PROP_FPS)
print('FPS is {0}'.format(fps))
get_framerate(vid)
MacOS Catalina
Python 3.7.4
I hope this helps you somehow. It is a simple calculator that takes cont captures and measure the beginning and the ending time. Then with the rule of three, i converted it to fps.
Related to you second question i read here that it could be due to bad installation. Also, you can check that your camera is working properly by printing ret variable. If it is true then you should be able to see the fps, if it is false then you can have an unpredictable result.
cv2.imshow() and key = cv2.waitKey(1) should be commented as it adds ping/delay resulting in bad measurement.
I post this as a comment because i do not have enough reputation points.
img = cv2.VideoCapture('rtsp://192.168.1.10/cam1/mpeg4')
while True:
if cont == 50:
a = datetime.now() - start
b = (a.seconds * 10e6 + a.microseconds)
print((a.seconds * 10e6 + a.microseconds), "fps = ", (50 * 10e6)/ b)
break
ret, frame = img.read()
# Comment for best test
cv2.imshow('fer', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
cont+=1
img.release()
cv2.destroyAllWindows()`

Can't get an Opencv, cv2.VideoCapture rtsp steam to work from IP camera

I am trying to read a rtsp stream from my Ip camera using Opencv and running Linux. The camera is a Floureon IPC 360 from China. I am trying to develop some facial recognition code.
I am using the following code:
import numpy as np
import cv2
vcap = cv2.VideoCapture("rtsp://192.168.1.240:554/realmonitor?channel=0")
print(vcap)
while(1):
ret, frame = vcap.read()
print (ret,frame)
cv2.imshow('VIDEO', frame)
#cv2.imwrite('messigray.png',frame)
cv2.waitKey(1)
$ python w.py
<VideoCapture 0x7fc685598230>
(False, None)
Traceback (most recent call last):
File "w.py", line 9, in <module>
cv2.imshow('VIDEO', frame)
cv2.error: OpenCV(4.1.0) /io/opencv/modules/highgui/src/window.cpp:352: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'
cv2.imshow is failing as the frame is 'None' & (ret is False).
In a separate window I can run openRTSP :
./openRTSP -4 -P 10 -F cam_eight -t -d 8 rtsp://192.168.1.240:554/realmonitor?channel=0
Which creates me a nice mp4 file that I can play:
107625 Sep 12 19:08 cam_eight-00000-00010.mp4
OpenRTSP works with or without the t (tcp).
I have also tried supplying the admin:123456 credentials to the cv2.VideoCapture line, which openRTSP doesn't appear to require.
Any ideas why cv2.VideoCapture is apparently failing ?
I have tried variants of the above code, but nothing seems to work.
I have enabled ONVIF on the camera
According to other answers, it isn't possible to acquire ONVIF streams with OpenCV, since it defaults the stream to use the tcp protocol, while ONVIF relies on udp.
You should define the environment variable OPENCV_FFMPEG_CAPTURE_OPTIONS to skip the default setting to tcp, as can be seen in the original source code here:
OPENCV_FFMPEG_CAPTURE_OPTIONS=whatever
If you want to properly configure the capture options, then you should refer to the ffmpeg documentation, which is used internally by OpenCV.
As stated in the linked answer, keys and values are separated with ; and pairs are separated via |.

opencv and python 3 -- cannot write video frames to disk

Python 3.5.2, anaconda 4.2.0 on Windows 10.
OpenCV installed from conda, version 3.1.0.
I'm trying to process a video file by opening it, transforming each frame, and putting the result into a new video file. The output file is created, but the size is about 800 bytes and its empty. The input file has ~4,000 frames and it's about 150 MB.
Here's my code, which follows the guide on the OpenCV documentation pretty closely.
import cv2
import progressbar
# preprocess video
# args.input is a valid file name
outname = 'foo.mp4'
cap = cv2.VideoCapture(args.input)
codec = int(cap.get(cv2.CAP_PROP_FOURCC))
framerate = app_config.camera.framerate #240
size = (app_config.camera.width, app_config.camera.height) #1080 x 720
vw = cv2.VideoWriter(filename=outname, fourcc=codec, fps=framerate, frameSize=size, isColor=False)
curframe = 0
with progressbar.ProgressBar(min_value=0, max_value=int(cap.get(cv2.CAP_PROP_FRAME_COUNT))) as pb:
while cap.isOpened():
ret, frame = cap.read()
if ret:
#update the progress bar
curframe += 1
pb.update(curframe)
# convert to greyscale
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# invert colors
inverted = cv2.bitwise_not(grey)
vw.write(inverted)
#cv2.imshow('right', right)
#if cv2.waitKey(1) & 0xFF == ord('q'):
# break
else:
break
cap.release()
vw.release()
cv2.destroyAllWindows()
I receive the following error:
OpenCV: FFMPEG: tag 0x7634706d/'mp4v' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'
I receive similar errors (as well as a warning that I have an incorrect environment variable for h.264 library path) if i try to set codec = cv2.VideoWriter_fourcc(*'H264').
Ensure that the dimensions of inverted match the dimensions of the size parameter in the videoWriter definition.
Also use 'M','P','4','V' codec with the .mp4 container.

CAP_PROP_FPS doesn't change in opencv 3

So I set
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FPS, 60)
I also tried integer 5 instead of cv2.CAP_PROP_FPS. Neverteless, frame rate doesn't change. I get 30 when I
print(cap.get(cv2.CAP_PROP_FPS))
Why?
The problem maybe is with the codec of the camera stream and not with the FPS itself, for example, if your camera only supports YUYV it is probably that you could only work with some specific FPS, try with the app guvcview to check this in a GUI.
Try to change the codec to MJPG and then change the FPS using CAP_PROP_FPS. I'm using a Logitech C922 pro and this works for me to configure 1080p and 30fps, if you have other camera probably yu need to use a lower resolution to achieve 30fps:
import cv2 as cv
def decode_fourcc(v):
v = int(v)
return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)])
def setfourccmjpg(cap):
oldfourcc = decode_fourcc(cap.get(cv.CAP_PROP_FOURCC))
codec = cv.VideoWriter_fourcc(*'MJPG')
res=cap.set(cv.CAP_PROP_FOURCC,codec)
if res:
print("codec in ",decode_fourcc(cap.get(cv.CAP_PROP_FOURCC)))
else:
print("error, codec in ",decode_fourcc(cap.get(cv.CAP_PROP_FOURCC)))
cap = cv.VideoCapture(CAMERANUM)
cu.setfourccmjpg(cap)
w=1920
h=1080
fps=30
res1=cap.set(cv.CAP_PROP_FRAME_WIDTH,w)
res2=cap.set(cv.CAP_PROP_FRAME_HEIGHT,h)
res3=cap.set(cv.CAP_PROP_FPS,fps)
then resume your normal video capture polling loop.
Not all openCV parameters are supported by all cameras from an opencv standpoint. Each camera has a different set of parameters that need to be set. You need to find out what parameters are supported by your camera...

Resources