VideoCapture のインデックスにも同様の問題がありました。4 つの USB Web カメラを取得しましたが、どの Web カメラがどのインデックスに対応しているかを知る必要があります。OpenCV は、カメラの識別をサポートするために縫い合わせていません。私は Mac OS 10.8 を使用しているため、Ubuntu の修正を提供することはできませんが、私の解決策がどこを見ればよいかのヒントになるかもしれません。opencv がカメラ情報を取得している OpenCV ソースを調べたところ、Mac OS-framework-(AVFoundation) が見つかりました。このフレームワークを使用して、ウェブカメラとそのハードウェア ID の順序を取得できました。この順序は VideoCapture クラスのカメラ インデックスに対応しており、再起動後などにインデックスの変更が問題になることはありません。
編集: MacOS の私の解決策: 私は Java で作業していて、jna または jni でラッパーを作成したくなかったので、コンソールにカメラの ID を出力する単純な Objective-C コマンドライン ツールを作成しました。その後、Java でRuntime.getRuntime().exec()を介してコマンドライン ツールを実行します。
Objective-c コマンドライン ツール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;
}
コンパイルする
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)
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();
}
Linux の代替ソリューションは、udev ルールを使用して OS 側でカメラの順序を修正することです。しかし、Mac OS には udev がないため、私はそれを試しませんでした。