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.