I am using OpenCV to open and read from several webcams. It all works fine, but I cannot seem to find a way to know if a camera is available.
I tried this code (cam 2 does not exist):
import cv2
try:
c = cv2.VideoCapture(2)
except:
print "Cam 2 is invalid."
But this just prints a lot of errors:
VIDEOIO ERROR: V4L: index 2 is not correct!
failed to open /usr/lib64/dri/hybrid_drv_video.so
Failed to wrapper hybrid_drv_video.so
failed to open /usr/lib64/dri/hybrid_drv_video.so
Failed to wrapper hybrid_drv_video.so
GStreamer Plugin: Embedded video playback halted; module v4l2src0 reported: Internal data stream error.
OpenCV Error: Unspecified error (GStreamer: unable to start pipeline
) in cvCaptureFromCAM_GStreamer, file /builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_gstreamer.cpp, line 832
VIDEOIO(cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, reinterpret_cast<char *>(index))): raised OpenCV exception:
/builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_gstreamer.cpp:832: error: (-2) GStreamer: unable to start pipeline
in function cvCaptureFromCAM_GStreamer
OpenCV Error: Unspecified error (unicap: failed to get info for device
) in CvCapture_Unicap::initDevice, file /builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_unicap.cpp, line 139
VIDEOIO(cvCreateCameraCapture_Unicap(index)): raised OpenCV exception:
/builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_unicap.cpp:139: error: (-2) unicap: failed to get info for device
in function CvCapture_Unicap::initDevice
CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate production trees: Can't create any node of the requested type!
<VideoCapture 0x7fa5b5de0450>
No exception is thrown. When using c.read() later, I do get False, but I would like to do this in the initialisation phase of my program.
So, how do I find out how many valid cameras I have or check if a certain number 'maps' to a valid one?
Using cv2.VideoCapture( invalid device number ) does not throw exceptions. It constructs a <VideoCapture object> containing an invalid device - if you use it you get exceptions.
Test the constructed object for None and not isOpened() to weed out invalid ones.
For me this works (1 laptop camera device):
import cv2 as cv
def testDevice(source):
cap = cv.VideoCapture(source)
if cap is None or not cap.isOpened():
print('Warning: unable to open video source: ', source)
testDevice(0) # no printout
testDevice(1) # prints message
Output with 1:
Warning: unable to open video source: 1
Example from: https://github.com/opencv/opencv_contrib/blob/master/samples/python2/video.py
lines 159ff
cap = cv.VideoCapture(source)
if 'size' in params:
w, h = map(int, params['size'].split('x'))
cap.set(cv.CAP_PROP_FRAME_WIDTH, w)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, h)
if cap is None or not cap.isOpened():
print 'Warning: unable to open video source: ', source
Another solution, which is available in Linux is to use the /dev/videoX device in the VideoCapture() call. The devices are there when the cam is plugged in. Together with glob(), it is trivial to get all the cameras:
import cv2, glob
for camera in glob.glob("/dev/video?"):
c = cv2.VideoCapture(camera)
Of course a check is needed on c using isOpened(), but you are sure you only scan the available cameras.
Here is a "NOT working" solution to help you prevent tumbling over in this pitfall:
import cv2 as cv
import PySpin
print (cv.__version__)
# provided by Patrick Artner as solution to be working for other cameras than
# those of Point Grey (FLIR).
def testDevice(source):
cap = cv.VideoCapture(source)
if cap is None or not cap.isOpened():
print('Warning: unable to open video source: ', source)
# ... PySpin / Spinnaker (wrapper/SDK libary) ...
system = PySpin.System.GetInstance()
cam_list = system.GetCameras()
cam = ''
cam_num = 0
for ID, cam in enumerate(cam_list):
# Retrieve TL device nodemap
if ID == cam_num:
print ('Got cam')
cam = cam
cam.Init()
# ... CV2 again ...
for i in range(10):
testDevice(i) # no printout
You can try this code:
from __future__ import print_function
import numpy as np
import cv2
# detect all connected webcams
valid_cams = []
for i in range(8):
cap = cv2.VideoCapture(i)
if cap is None or not cap.isOpened():
print('Warning: unable to open video source: ', i)
else:
valid_cams.append(i)
caps = []
for webcam in valid_cams:
caps.append(cv2.VideoCapture(webcam))
while True:
# Capture frame-by-frame
for webcam in valid_cams:
ret, frame = caps[webcam].read()
# Display the resulting frame
cv2.imshow('webcam'+str(webcam), frame)
k = cv2.waitKey(1)
if k == ord('q') or k == 27:
break
# When everything done, release the capture
for cap in caps:
cap.release()
cv2.destroyAllWindows()
Related
I am working on a project that has to detect a USB camera (CM3-U3-13S2C-CS a 1.3 Megapixel USB 3.0 camera), opencv failed to detect the id of the camera I have tried the code below to display the IDS of available cameras but all that openCV detects is the ID of the webcam, the camera is working fine on Labview.
I would really appreciate any help !
> import cv2
>
> openCvVidCapIds = []
>
> for i in range(100):
> try:
> cap = cv2.VideoCapture(i)
> if cap is not None and cap.isOpened():
> openCvVidCapIds.append(i)
> # end if
> except:
> pass
> # end try
> # end for
>
> print(str(openCvVidCapIds))
which OS are you running your OpenCV codes? have you checked if your USB camera is shown up in your OS device layers?
for windows, in the Device Manager under the "Imaging devices" tree
for Linux, in /dev like "/dev/video1" and "/dev/video2" and then do
cap =
cv2.VideoCapture("/dev/videox")
I am developing a simple program which loads an external camera through USB connection. When I run the program for the first time, it loads the camera and executes the rest of the code successfully. But if I stop the execution and try to re-run the program, it doesn't load the camera. Yet, if I remove the USB cable and plug it again, the program runs perfectly (The error still occurs if I re-run the program)
Below is my implementation,
import cv2 as cv
import pytesseract
import imutils
capture = cv.VideoCapture(0)
pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
temperature = 0
tot = 0
for i in range(10):
_, frame = capture.read()
frame = imutils.resize(image=frame, width=500)
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
frame_gray = frame_gray[:50, :88]
cv.imshow('frame', frame)
try:
temperature = float(pytesseract.image_to_string(frame_gray))
tot = tot + temperature
except ValueError:
print('except')
cv.imshow('Frame', frame_gray)
if cv.waitKey(20) & 0xFF == ord('q'):
break
print(tot / 10)
capture.release()
cv.destroyAllWindows()
And below is the generated error when I run the program for the second time
[ WARN:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-5rb_9df3\opencv\modules\videoio\src\cap_msmf.cpp (372) `anonymous-namespace'::SourceReaderCB::OnReadSample videoio(MSMF): OnReadSample() is called with error status: -2147023901
[ WARN:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-5rb_9df3\opencv\modules\videoio\src\cap_msmf.cpp (384) `anonymous-namespace'::SourceReaderCB::OnReadSample videoio(MSMF): async ReadSample() call is failed with error status: -2147023901
[ WARN:1] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-5rb_9df3\opencv\modules\videoio\src\cap_msmf.cpp (912) CvCapture_MSMF::grabFrame videoio(MSMF): can't grab frame. Error: -2147023901
Traceback (most recent call last):
File "D:\Studies\OpenCV\Lab07\Lab.py", line 15, in <module>
frame = imutils.resize(image=frame, width=500)
File "C:\Python39\lib\site-packages\imutils\convenience.py", line 69, in resize
(h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'
[ WARN:1] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-5rb_9df3\opencv\modules\videoio\src\cap_msmf.cpp (434) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
So basically I have to plug out and plug in the USB cable in order to re-run the program. How can I solve this issue? Thanks in advance!
in first time try to use the method cv.VideoCapture.open and check that it returns True or in the same principle use cv.VideoCapture.isOpened
using open() method call release() before opening a new device
capture = cv.VideoCapture()
capture.open(0)
if not capture.IsOpened() :
...
...
capture.release()
warning be sure to call release() before exit the script
the problem can also come from your camera, check with another one
I am running the following code on Raspberry Pi with pi camera, I have the broadcom drivers for it and all, but I am getting an error. Perhaps something to do with the dimensions of the video feed, but I do not know how to set it on Linux.
Code:
import cv2
import numpy as np
cap = cv2.VideoCapture()
while True:
ret, img = cap.read()
cv2.imshow('img', img)
if cv2.waitKey(0) & 0xFF == ord('q):
break
Error:
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow,
file /home/pi/opencv-3.3.0/modules/highgui/src/window.cpp, line 325
Traceback (most recent call last):
File "check_picam_with_opencv.py", line 10, in <module>
cv2.imshow('img', img)
cv2.error: /home/pi/opencv-3.3.0/modules/highgui/src/window.cpp:325: error:
(-215) size.width>0 && size.height>0 in function imshow
Provide an id to VideoCapture.
cap = cv2.VideoCapture(0)
Also check the value of ret, see if it's TRUE or FALSE
print (ret)
Edit:
To capture a video, you need to create a VideoCapture object. Its argument can be either the device index or the name of a video file. Device index is just the number to specify which camera.
cap = cv2.VideoCapture(0)
To check whether the cap has been initialized or not, you can use cap.isOpened() function, which returns True for successful initialization and False for failure.
if cap.isOpened() == False:
print ("VideoCapture failed")
cap.read() returns a bool (True/False). If frame is read correctly, it will be True. So you can check end of the video by checking this return value.
ret, frame = cap.read()
if ret == False:
print("Frame is empty")
Further reading here.
I've got a script in Python which reads out my webcam and shows it in a window. I now want to store the results, so following this tutorial I wrote the following code:
import cv2
import imutils
camera = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object to save the video
fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_writer = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while True:
try:
(grabbed, frame) = camera.read() # grab the current frame
frame = imutils.resize(frame, width=640, height=480)
cv2.imshow("Frame", frame) # show the frame to our screen
key = cv2.waitKey(1) & 0xFF # I don't really have an idea what this does, but it works..
video_writer.write(frame) # Write the video to the file system
except KeyboardInterrupt:
break
# cleanup the camera and close any open windows
camera.release()
video_writer.release()
cv2.destroyAllWindows()
print "\n\nBye bye\n"
This perfectly shows the real time video footage from my webcam in a new window. But writing the video file seems to fail. It does create a file called output.avi, but the file is empty (zero bytes) and on the command line I see the following errors:
OpenCV: Frame size does not match video size.
OpenCV: Frame size does not match video size.
OpenCV: Frame size does not match video size.
etc.
I clearly resize the frame to the size in which I want to save the video (640x480) so I'm not sure why it wouldn't match.
When I run the script again (so in this case the empty output.avi already exists), it shows these errors:
2017-04-17 10:57:14.147 Python[86358:5848730] AVF: AVAssetWriter status: Cannot Save
2017-04-17 10:57:14.332 Python[86358:5848730] mMovieWriter.status: 3. Error: Cannot Save
2017-04-17 10:57:14.366 Python[86358:5848730] mMovieWriter.status: 3. Error: Cannot Save
2017-04-17 10:57:14.394 Python[86358:5848730] mMovieWriter.status: 3. Error: Cannot Save
etc.
In the tutorial it says that the Four digit FourCC code is used to specify the video codec which is platform dependent and that the list of available codes can be found in fourcc.org. I'm on OSX so I tried a bunch of different codec-codes: DIVX, XVID, MJPG, X264, WMV1, WMV2. But unfortunately none of them work for me. They all give the same errors, except for MJPG, which gives me the following error:
OpenCV Error: Assertion failed (img.cols == width && img.rows == height && channels == 3) in write, file /tmp/opencv3-20170216-77040-y1hrk1/opencv-3.2.0/modules/videoio/src/cap_mjpeg_encoder.cpp, line 829
Traceback (most recent call last):
File "store_video.py", line 15, in <module>
video_writer.write(frame) # Write the video to the file system
cv2.error: /tmp/opencv3-20170216-77040-y1hrk1/opencv-3.2.0/modules/videoio/src/cap_mjpeg_encoder.cpp:829: error: (-215) img.cols == width && img.rows == height && channels == 3 in function write
Does anybody know what could be wrong here? All tips are welcome!
It's probably because you built OpenCV with AVFoundation and it doesn't support XVID or other codec. You can try mp4v and m4v extension.
import cv2
camera = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object to save the video
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
video_writer = cv2.VideoWriter('output.m4v', fourcc, 30.0, (640, 480))
while True:
(grabbed, frame) = camera.read() # grab the current frame
frame = cv2.resize(frame, (640,480))
cv2.imshow("Frame", frame) # show the frame to our screen
key = cv2.waitKey(33) & 0xFF # I don't really have an idea what this does, but it works..
video_writer.write(frame) # Write the video to the file system
if key==27:
break;
# cleanup the camera and close any open windows
camera.release()
video_writer.release()
cv2.destroyAllWindows()
print("\n\nBye bye\n")
On the other note, the error
OpenCV Error: Assertion failed (img.cols == width && img.rows == height && channels == 3) in write, file /tmp/opencv3-20170216-77040-y1hrk1/opencv-3.2.0/modules/videoio/src/cap_mjpeg_encoder.cpp, line 829
means that you messed up the dimension with
frame = imutils.resize(frame, width=640, height=480)
You can try cv2.resize as I used in my code. There's no need to use another library when cv2 can do that already.
I have the following code for connecting one usb camera and two arduino board with raspberry pi.
import cv2.cv as cv, time
import numpy as np
import serial,time
ser1 = serial.Serial('/dev/ttyUSB0')
ser2 = serial.Serial('/dev/ttyUSB1')
capture = cv.CaptureFromCAM(0)
while True:
try:
for i in range(10):
x = ser1.readline()
with open("test1.txt", "a") as myfile:
myfile.write(x)
img = cv.QueryFrame(capture)
print("Taking image...")
cv.SaveImage('pic{:>05}.jpg'.format(i), img)
time.sleep(2)
y = ser2.readline()
with open("test2.txt", "a") as myfile:
myfile.write(y)
cv.WaitKey(1)
except:
continue
The camera is for taking continuous image frame and storing the latest 10 images in the current folder in each 2sec(Overwriting previous data). The datas from the arduino also logging into two separate text file. While running the code i am getting error messages as shown below.
pi#raspberrypi ~ $ sudo python accident.py
libv4l2: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Device or resource busy
libv4l1: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl VIDIOCSPICT
Taking image...
Taking image...
Taking image...
^Z
[4]+ Stopped
While I searched for this problem , I found that, all the USB port of rasp-pi having the same serial port.
Can anybody help me to solve this issue...