For context: I am figuring out how to use VidGear since I had weird problems with cv2 within threadpools.
The question: How can I confirm if a webcam is connected or not? I was using something like:
import cv2
camtest = cv2.VideoCapture(0)
camcheck = camtest.isOpened()
and that returned "True" or "False" so I was able to use it to trigger conditions.
What would be the VidGear equivalent ?
Thank You,
Related
mediapipe==0.8.10.1
I'm trying to make a project based on mediapipe, and I've installed the package normally using
pip install mediapipe
I'm running this in the VS Code editor within a venv which has access to global packages,
import cv2
import mediapipe as mp
# why do I need to do this, instead of simply
# "mpHands = mp.solutions.hands"
# to access the hands function because otherwise it doesn't recognize the module
mpHands = mp.solutions.mediapipe.python.solutions.hands
Hands = mpHands.Hands() # doesn't recognize unless I do the entire line above
capture = cv2.VideoCapture(0)
while True:
ret, img = capture.read()
cv2.imshow("res", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
From the google github and other tutorials, "mp.solutions.hands" would be the usual way to call the module, but after some head scratching I've noticed that I need to use "mp.solutions.mediapipe.python.solutions.hands"
to access the "Hands()" module, otherwise it's unrecognized.
Moreover this only happens with mediapipe and not with, for example opencv.
I'm really not sure why this happens; I am new to package handling so any advice would be appreciated,
thank you.
I have the following code that prints out the names of USB cameras connected to my PC:
import wmi
c = wmi.WMI()
wql = "Select * From Win32_USBControllerDevice"
for item in c.query(wql):
a = item.Dependent.PNPClass
b = item.Dependent.Name.upper()
if (a.upper() == 'MEDIA' or a.upper() == 'CAMERA') and 'AUDIO' not in b:
print(item.Dependent.Name)
The problem with this code is that it only works in Windows. I want to alter this code so that it works on all operating systems. I know that I have to use something other than wmi, since wmi only works in Windows. So, I was thinking about using an ffmpeg wrapper called ffmpy. So maybe I could convert the code to use ffmpy? I got the code above from the following SO post: Associate USB Video Capture Device Friendly Name with OpenCV Port Number in Python. Any help would be much appreciated! Thanks!
You can give pygrabber a shot. "# This code lists the cameras connected to your PC:" (source)
from pygrabber.dshow_graph import FilterGraph
graph = FilterGraph()
print(graph.get_input_devices())
# ['Integrated Webcam', 'EpocCam Camera']
The answer to this question is no; there is no OS-independent way of getting the names of USB cameras connected to your PC. However, there is platform-specific code that can get the job done: https://stackoverflow.com/a/68402011/13386603
I'm having some trouble enumerating over cameras in Python over multiple OS's.
Here's some of the approaches I've tried:
import cv2 as cv
num = 0
while 1:
cap = cv.VideoCapture(num)
if cap.isOpened():
# working capture
num += 1
else:
break
The downsides of using Opencv is that Opencv doesn't provide any friendly display name. Additionally, enumerating over cameras is slow, as you need to actually open and close the camera to check if it's a valid camera.
I've also tried using libraries like PyPylon and pyuvc. They work, but only for specific brands.
I've done some researching on stack overflow, and some people have suggested python's gstreamer bindings as a possible OS independent solution. This is what I have so far.
import pgi
pgi.require_version("Gtk", "3.0")
pgi.require_version("Gst", "1.0")
pgi.require_version("GstVideo", "1.0")
from pgi.repository import Gtk, GObject, Gst, GstVideo
Gst.init("")
dm = Gst.DeviceMonitor()
dm.set_show_all_devices(True)
dm.start()
print("Displaying devices.")
for device in dm.get_devices():
print(device.get_display_name())
print("Displaying providers.")
for provider in dm.get_providers():
print(provider)
dm.stop()
This is the output I'm getting:
Displaying devices.
papalook Microphone
DisplayPort
HDMI
Built-in Output
Built-in Microph
Displaying providers.
osxaudiodeviceprovider
For some reason, I'm not getting any webcams, but only audio devices.
Any ideas on what I'm doing wrong?
Any different approaches I should be taking?
Thanks.
I recently encountered this problem and didn't even realize how hard it is!
Sharing here my solution, hopefully it helps someone.
As already pointed out, there is no easy way of doing this in a cross platform manner and we still need to write platform specific code.
My solution is actually combination of some of the approaches offered here, so let's break it down.
1. Get the index of a camera
First thing we want to tackle is how many camera devices is connected to the computer.
We can use OpenCV for this and the approach that was already mentioned above.
2. Linux
Linux stores information about video devices at /sys/class/video4linux
Since we know the index of each camera, we can do something like this to get extra info.
cat /sys/class/video4linux/video1/name
3. Windows
Windows provides a bunch of useful APIs through the Windows Runtime also known as WinRT.
Microsoft provides a Python library for this and to get the camera information we need to use DevicesEnumeration API.
4. MacOS
For MacOs, we can use a similar approach as for Linux. It seems that the ioreg and system_profiler commands can provide camera name information.
Unfortunately, I don't have a MacOS system to test this out so I left a TODO. It would be great if someone can try and share it.
Here is my code.
import asyncio
import platform
import subprocess
import cv2
if platform.system() == 'Windows':
import winrt.windows.devices.enumeration as windows_devices
VIDEO_DEVICES = 4
class Camera:
def __init__(self):
self.cameras = []
def get_camera_info(self) -> list:
self.cameras = []
camera_indexes = self.get_camera_indexes()
if len(camera_indexes) == 0:
return self.cameras
self.cameras = self.add_camera_information(camera_indexes)
return self.cameras
def get_camera_indexes(self):
index = 0
camera_indexes = []
max_numbers_of_cameras_to_check = 10
while max_numbers_of_cameras_to_check > 0:
capture = cv2.VideoCapture(index)
if capture.read()[0]:
camera_indexes.append(index)
capture.release()
index += 1
max_numbers_of_cameras_to_check -= 1
return camera_indexes
# TODO add MacOS specific implementations
def add_camera_information(self, camera_indexes: list) -> list:
platform_name = platform.system()
cameras = []
if platform_name == 'Windows':
cameras_info_windows = asyncio.run(self.get_camera_information_for_windows())
for camera_index in camera_indexes:
camera_name = cameras_info_windows.get_at(camera_index).name.replace('\n', '')
cameras.append({'camera_index': camera_index, 'camera_name': camera_name})
return cameras
if platform_name == 'Linux':
for camera_index in camera_indexes:
camera_name = subprocess.run(['cat', '/sys/class/video4linux/video{}/name'.format(camera_index)],
stdout=subprocess.PIPE).stdout.decode('utf-8')
camera_name = camera_name.replace('\n', '')
cameras.append({'camera_index': camera_index, 'camera_name': camera_name})
return cameras
async def get_camera_information_for_windows(self):
return await windows_devices.DeviceInformation.find_all_async(VIDEO_DEVICES)
camera = Camera()
For Windows you can use the library pygrabber which is a pure python tool to capture photos from cameras and for doing simple image processing using DirectShow and OpenCV. It also enumerates the connected webcams like so:
from __future__ import print_function
from pygrabber.dshow_graph import FilterGraph
graph = FilterGraph()
print(graph.get_input_devices())
I have modified the library to work under Python 2 and 3. Download at:
https://github.com/bunkahle/pygrabber
Original source only for Python 3:
https://github.com/andreaschiavinato/python_grabber
I have searched everywhere and I find it truly amazing that there is no reference on the chamerMatching function, especially in Python. Someone else also had the same problem with no answer:
I don't really want to know about the algorithm - I know how the algorithm works - I want to know how to call it in Python and retrieve the costs, results and bestfit. I have tried the following code.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
frame = cv2.GaussianBlur(frame, (13, 13), 0)
frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame = cv2.adaptiveThreshold(frame,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
templ = cv2.imread("template.png",cv2.CV_LOAD_IMAGE_GRAYSCALE)
cannyframe = cv2.Canny(frame,5,50,apertureSize=3)
cannytempl = cv2.Canny(templ,5,50,apertureSize=3)
cv2.imshow("cannyframe",cannyframe)
cv2.imshow("cannytempl", cannytempl)
cv2.waitKey(0)
#The line below, and NOT any other line, crashes the program
cv2.chamerMatching(cannytempl,cannyframe)
All of it runs fine except the final call to the chamerMatching function which causes the python interpreter to crash and stop working for some reason with a message that looks like this:
With absolutely zero documentation on the function, I can't figure out why.
EDIT:
The code above now includes all the required lines to run and below is template.png.
i don't know if you still need this information. But I also needed chamfer matching for my research. And here's what I found after encountering the same dilemma as you've had.
http://code.opencv.org/issues/3602
:)
having recently learned the basics of python, I thought I would dive in with a small project to build on.
A webcam application. I would then add tools as I developed my skills.
I have installed matplotlib, CV, numpy, and various others,the code I found:
import cv
cv.namedWindow("lll")
cap = cv.VideoCapture(0)
while( cap.isOpened() ) :
ret,img = cap.read()
cv.imshow("lll",img)
k = cv.waitKey(10)
if k == 27:
break
Now the initial "video Source" dialogue comes up, I select my webcam and press OK.
Then I get an error:
while(cap.isOpened()):
SystemError: null argument to internal routine
Done a bit of googling. Found others with the same issue but no resolution...
Any tips?
Sorry for not addressing your specific problem, but you can always use the newer cv2 module:
import cv2
cv2.namedWindow("lll")
cap = cv2.VideoCapture(0)
while True:
ret,img = cap.read()
cv2.imshow("lll",img)
k = cv2.waitKey(10)
if k == 27:
break
Sounds like something that would require digging into the source of PyCV (or whatever the interface to OpenCV is called) to fix. My tip to you would be to go to the OpenCV IRC-channel and ask or/and file a bug report.