Address Order of Firewire Cameras in OpenCV+Linux

297 views Asked by At

I have 4 Unibrain Fire-I cameras daisy-chained to my computer (Ubuntu 12.10), and an app written with OpenCV that right now reads frames from 2 of these cameras. However, I'm discovering that every time I plug/unplug the firewire connector to my computer the addresses change. What identifies in cv::VideoCapture as "0" in one run, changes to number 3 in the next.

Is there some better way to identify cameras that is more reliable that by using the number?

1

There are 1 answers

1
mirel7c3 On

I had a similar problem with the indexes of VideoCapture. I got 4 USB Webcams and I need to know which webcam corresponds to which index. OpenCV does not seam to support any identification of the cameras. I'm using Mac OS 10.8 so I cant offer you a fix for Ubuntu but maybe my solution can give you hint where to look. I looked up in the OpenCV sources where opencv is retrieving the camera information and found the Mac OS-framework-(AVFoundation). Using this framework i managed to get the order of the webcams and their hardware ids. This order corresponds with camera indexes for the VideoCapture class making index change e.g. after reboot no longer a problem.

Edit: my solution for MacOS: Since I'm working with java and I didn't want to build a wrapper with jna or jni, i created a simple objective-c commandline-tool which prints the id's of the cameras on console. Afterwards i execute the commandline tool via Runtime.getRuntime().exec() in java.

Objective-c commandline tool main.m

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

int main() {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    AVCaptureDevice *device;
    NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (int i=0; i<[devices count]; i++) {
        device = [devices objectAtIndex:i];
        NSString *devUid = [device uniqueID];
        NSString *devName = [device localizedName];
        printf("%s\n", [devUid cStringUsingEncoding:NSUTF8StringEncoding]);
    }

    [pool release];
    return 1;
}

to compile

user$ cc -framework Foundation -framework AVFoundation -o printCameras main.m
user$ ./printCameras
uid:0xfd1200000c4562f1_name:USB 2.0 Camera
uid:0xfa20000005ac8509_name:FaceTime HD Camera (Built-in)

snippt for java

ArrayList<String> cameras = new ArrayList<String>();

try {
    String line;
    Process process = Runtime.getRuntime().exec("./printCamerasMacOs");
    Reader r = new InputStreamReader(process.getInputStream());
    BufferedReader in = new BufferedReader(r);
    while((line = in.readLine()) != null) {
        cameras.add(line);
    }
    in.close();
} catch (IOException e) {
    e.printStackTrace();
} 

An alternative solution for linux might be to use a udev rule to fix the camera order on the OS-side. But I didn't experimented with that since Mac OS is lacking udev.