我有 4 台 Unibrain Fire-I 相机以菊花链方式连接到我的计算机(Ubuntu 12.10),还有一个用 OpenCV 编写的应用程序,现在可以从其中 2 台相机中读取帧。但是,我发现每次将火线连接器插入/拔出计算机时,地址都会更改。在一次运行中将 cv::VideoCapture 中标识为“0”的内容在下一次更改为数字 3。
有没有更好的方法来识别比使用数字更可靠的摄像机?
我对 VideoCapture 的索引也有类似的问题。我有 4 个 USB 网络摄像头,我需要知道哪个网络摄像头对应于哪个索引。OpenCV 不支持任何摄像机识别。我使用的是 Mac OS 10.8,所以我无法为您提供 Ubuntu 的修复,但也许我的解决方案可以提示您在哪里查看。我在 OpenCV 源中查找了 opencv 正在检索相机信息的地方,并找到了 Mac OS-framework-(AVFoundation)。使用这个框架,我设法获得了网络摄像头的顺序及其硬件 ID。此顺序对应于 VideoCapture 类的摄像头索引,使得索引更改(例如重新启动后不再是问题)。
编辑:我的 MacOS 解决方案:由于我正在使用 java 并且我不想使用 jna 或 jni 构建包装器,因此我创建了一个简单的 Objective-C 命令行工具,它可以在控制台上打印相机的 ID。之后我通过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 规则来修复操作系统端的摄像头顺序。但我没有尝试过,因为 Mac OS 缺少 udev。