Open USB Camera using OpenCV - c++

I want to open a USB camera with OpenCV in C++ operating on Linux Mint 18.3.
The Camera is plugged in and works fine with the SoftwareSuite by Common Vision Blocks.
From command lsusb I got the following output:
Bus 002 Device 005: ID 1ab2:0001
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 0cf3:e300 Atheros Communications, Inc.
Bus 001 Device 003: ID 1bcf:2b95 Sunplus Innovation Technology Inc.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The first entry seems to be the camera because the entry doesn't exist if the camera is unplugged. But I don't understand why there isn't a name shown.
Then I found on the internet that the USB camera is found under the path:
/dev/v4l/by-id/ or /dev/v4l/by-path/. The entry for /dev/v4l/by-id/ is:
usb-CNFEH73N3462520017B2_Integrated_Webcam_HD-video-index0
and the entry for /dev/v4l/by-path/ is:
pci-0000:00:14.0-usb-0:12:1.0-video-index0
So I want to open it with OpenCV by using:
VideoCapture
cap("/dev/v4l/by-id/usb-CNFEH73N3462520017B2_Integrated_Webcam_HD-video-index0");
I use Clion as an IDE and run it normally as root, but in both cases I get the following error:
GStreamer Plugin: Embedded video playback halted; module source reported: Could not read from resource.
OpenCV Error: Unspecified error (GStreamer: unable to start pipeline) in cvCaptureFromCAM_GStreamer
/opencv-3.0.0/modules/videoio/src/cap_gstreamer.cpp, line 773 terminate called after throwing an instance of 'cv::Exception'
How can I open the USB camera and being on the right way to open it with dev/v4l/?

You should open a device by int id. Try with:
VideoCapture cap(0);
In fact, passing a string OpenCV expects to open a playback file, an MPEG file for example, as described in the documentation.
This is working but the problem is that the opened camera is the integrated camera, the one reported by lsusb as:
Bus 001 Device 003: ID 1bcf:2b95 Sunplus Innovation Technology Inc.
which actually is /dev/video0, linked by:
/dev/v4l/by-path/pci-0000:00:14.0-usb-0:12:1.0-video-index0
Instead the lsusb entry listed as:
Bus 002 Device 005: ID 1ab2:0001
which is the externally plugged camera, seems not recognized as V4L device. I don't know "SoftwareSuite by Common Vision Blocks", so I have no idea, whether this software is able to work with it as RAW device.

Related

Capturing an Android Camera Stream over USB with C/C++ and libusb

I've done some research on this and have already tried using IP WebCam and gstreamer to pipe the video stream from the IP based source to /dev/videoX and reading from that.
It works fine, but it isn't exactly what I am looking for. I have several old useless phones that I would like to use on a robot as video sources from multiple angles for computer vision based tasks.
I've also read that DroidCam does this, but I have read terrible reviews about the app and especially the USB based part.
Most likely this robot will not be near any WiFi (or rather should not require it), and the phones will not have a network connection (no SIM card), so no USB tethering.
It seems like there should be a very simple way to do this. Is there a way to uselibusb and maybe adb to capture the video stream from an Android phone connected to an Ubuntu box with USB?

C/C++ How to get the usb subsystem path for a USB libudev hidraw device?

I'm using libudev in C/C++ with the hidraw subsystem to enumerate and communicate with custom HID devices - working well. My devices are assigned specific usb plugs and they are "hot swappable" - I need to know which plug is connected to each hidraw device. Is there a correspondence between the usb and the hidraw subsystems and how to get the usb path which details the interface route (like: /dev/bus/usb/002/001 and not the hidraw path) for each device from its hidraw device pointer?
i think with hidraw device pointer you mean the device nodes like /dev/hidraw0 or similar
Hidraw uses a dynamic major number, meaning that udev should be relied
on to create hidraw device nodes. Udev will typically create the
device nodes directly under /dev (eg: /dev/hidraw0). As this location
is distribution- and udev rule-dependent, applications should use
libudev to locate hidraw devices attached to the system. There is a
tutorial on libudev with a working example at:
http://www.signal11.us/oss/udev/
linux has two species of device nodes, one created by device drivers i.e. /dev/sdb for a mass storage device and raw device nodes like /dev/bus/usb/BBB/DDD where BBB is the bus number and DDD is the device number, that are created by the kernel directly :
USB Device Issues
USB devices usually have two kinds of device nodes associated with
them.
The first kind is created by device-specific drivers (e.g.,
usb_storage/sd_mod or usblp) in the kernel. For example, a USB mass
storage device would be /dev/sdb, and a USB printer would be
/dev/usb/lp0. These device nodes exist only when the device-specific
driver is loaded.
The second kind of device nodes (/dev/bus/usb/BBB/DDD, where BBB is
the bus number and DDD is the device number) are created even if the
device doesn't have a kernel driver. By using these "raw" USB device
nodes, an application can exchange arbitrary USB packets with the
device, i.e., bypass the possibly-existing kernel driver.
source : http://www.linuxfromscratch.org/blfs/view/7.10/postlfs/devices.html
you want to establish a link between the kernel module device node ( i.e. /dev/hidraw0 ) and the corresponding raw device node ( i.e /dev/bus/usb/BBB/DDD )
you can get the bus address (BBB and DDD ) from the device node using sudo udevadm info -a -p $(sudo udevadm info -q path -n /dev/hidraw0) ( ATTRS{busnum}=="BBB" and ATTRS{devnum}=="DDD" in the output ) however this is a bit ugly
in Find bus number and device number with device file symlink is code using libudev to get bus number BBB and device number DDD for a specific device node in /dev/ i.e. /dev/hidraw0 it uses udev_device_get_sysattr_value(dev, "devnum")); to get DDD in /dev/bus/usb/BBB/DDD and udev_device_get_sysattr_value(dev, busnum")); to get BBB
you can also get BBB and DDD from sysfs ( /sys/devices/ ... ) :
/sys/devices/pci0000:00/0000:00:12.2/usb2/2-5/2-5.4$ ls 2-5.4:1.0
bDeviceSubClass configuration idProduct remove authorized
bmAttributes descriptors idVendor serial
avoid_reset_quirk bMaxPacketSize0 dev manufacturer
speed bcdDevice bMaxPower devnum
maxchild subsystem bConfigurationValue bNumConfigurations devpath
power uevent bDeviceClass bNumInterfaces driver
product urbnum bDeviceProtocol busnum
ep_00
quirks version
source : http://www.signal11.us/oss/udev/
to get the sysfs path of your device ( the /sys/devices/pci0000:00/0000:00:12.2/usb2/2-5/2-5.4 above ) use sudo udevadm info -q path -n /dev/hidraw0
( https://unix.stackexchange.com/questions/344784/how-to-map-sys-bus-usb-devices-to-dev-video )
Hope it's helpful but IIRC, you cannot reliably (with port# being same between insert events) enumerate individual ports on hubs that are connected downstream from a main USB controller point. I think that was one of the reasons we started seeing lots and lots of USB controllers on MB's after USB came out; because when chaining everything off downstream hubs, besides negatively affecting bandwidth, also caused problems with persistent software numbering issues.
I believe when a device is plugged into a USB port directly connected to a USB controller, you can reliably get the same exact port# it's connected to. But when doing that from a downstream multi-port USB hub connected upstream to a USB port from a USB controller, the actual port# on the USB hub does not get passed upstream or even if it does, it is not a predictable port# between insertions/power-resets in the same hub port.

How to set a specific device ID on OpenNIGrabber?

how can I set a specific device ID to the constructor of the OpenNIGrabber object?
The tutorial example with OpenNIGrabber("#1") or OpenNIGrabber("#2") works well but I need to select a specific device somehow.
Is it possible to choose the device connected to a specific USB port?
I'm using some Xtion PRO.
I'm on ubuntu 13.04 64bit.
You can use bus#address ID where bus number and USB port address (device) can be looked up with lsusb command on Linux. This type of device ID works only on non-Windows systems as you can see in PCL sources (https://github.com/PointCloudLibrary/pcl/blob/master/io/src/openni_grabber.cpp#L352-L361, method pcl::OpenNIGrabber::setupDevice, lines 352-361).
Also you can use ASUS Xtion Pro's serial number as an ID.
More in PCL documentation: http://docs.pointclouds.org/1.7.2/a00897.html#a5753a422ff92067c9065797697d69244
Example
quepas#ubuntu:~$ lsusb
Bus 001 Device 002: ID 1d27:0601 ASUS
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Then:
OpenNIGrabber("1#2")

How to access USB barcode scanner data directly from USB port using C/C++ without driver

Currently I am working on USB port programming for Linux to fully control USB ports. I am running Ubuntu 13.04 and am trying to read data from ttySX files for USB port and also from /dev/bus/usb. But I am not getting any results.
I searched and found ttyUSBX port, but in my case there is no tty. Also, the problem is that the manufacturer of my USB barcode scanner does not provide a driver for linux. So can any one suggest me how to read data from USB port without a driver?
Most barcode scanners can work as simple usb-to-serial converters and thus you get a ttyusbx device in /dev. The way this usually works is you download some software or manual from the manufacturer's website and scan a barcode or a series of barcodes that put the device in this mode.
Even simpler, ALL barcode scanners should work as HID devices(keyboard)...again this requires downloading some sort of software or manual and scanning a couple barcodes.
Any chance you could provide the scanner's make and model?

How to find what device is connected to USB port (HID or Disk drive) in C++

I have managed to enumerate all the connected USB ports using SetupDi calls. Sample code is available at this link.
Please could any one tell me how can I find what device is connected to USB port like whether it is any HID device or any Disk drive?
Thanks.
I would recommend looking at the USBView sample in the WDK. If you are unfamiliar with this, simply run it - this tool walks the entire USB tree on the system and prints out information and descriptor listings for each device.
In your case, I'd start at the RefreshTree() function in this sample, you can then follow the code to see how it enumerates the host controllers, hubs and finally devices. For each device that you find you can look at the bInterfaceClass in the interface descriptors to find out what types of interfaces it is advertising (in your case 0x03 for HID Interface Class and 0x08 for Mass Storage Class).
The easiest way to get the source to this sample is to install the 7.1.0 WDK which is currently available here:
http://www.microsoft.com/en-us/download/details.aspx?id=11800