关于#opencv#的问题,如何解决?

opencv获取摄像头编号相关问题
windows系统下,请问如果多摄像头的情况,对同名摄像头怎么处理可以获取同名摄像头的设备编号用于opencv的打开摄像头接口
现在需要使用摄像头名称来打开摄像头,但是如果连接了同名摄像头就没法打开另一个了。
获取摄像头列表的代码如下:

int listDevices(vector<string>& list)
{
    ICreateDevEnum *pDevEnum = NULL;
    IEnumMoniker *pEnum = NULL;
    int deviceCounter = 0;
    CoInitialize(NULL);

    HRESULT hr = CoCreateInstance(
        CLSID_SystemDeviceEnum,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_ICreateDevEnum,
        reinterpret_cast<void**>(&pDevEnum)
    );

    if (SUCCEEDED(hr))
    {
        hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
        if (hr == S_OK) {

            IMoniker *pMoniker = NULL;
            while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
            {
                IPropertyBag *pPropBag;
                hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
                    (void**)(&pPropBag));

                if (FAILED(hr)) {
                    pMoniker->Release();
                    continue; // Skip this one, maybe the next one will work.
                }

                VARIANT varName;
                VariantInit(&varName);
                hr = pPropBag->Read(L"Description", &varName, 0);
                if (FAILED(hr))
                {
                    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                }

                if (SUCCEEDED(hr))
                {
                    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                    int count = 0;
                    char tmp[255] = { 0 };
                    while (varName.bstrVal[count] != 0x00 && count < 255)
                    {
                        tmp[count] = (char)varName.bstrVal[count];
                        count++;
                    }
                    list.push_back(tmp);
                }

                pPropBag->Release();
                pPropBag = NULL;
                pMoniker->Release();
                pMoniker = NULL;

                deviceCounter++;
            }

            pDevEnum->Release();
            pDevEnum = NULL;
            pEnum->Release();
            pEnum = NULL;
        }
    }
    return deviceCounter;
}

int find_index_from_name(char* camera_name) {
    if (!camera_name) {
        return -1;
    }
    string s_camera_name = camera_name;
    vector<string> CameraName;//存储摄像头名称
    int num = listDevices(CameraName);
    //cout << "摄像头个数:" << num << endl;
    if (num < 1) {
        return -1;
    }
    vector <string> ::iterator i;
    i = find(CameraName.begin(), CameraName.end(), s_camera_name);
    if (i == CameraName.end()) { return -1; }
    else { return i - CameraName.begin(); }

}
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7646580
  • 你也可以参考下这篇文章:windows opencv新手读取视频或摄像头,一闪而过,只显示第一帧
  • 除此之外, 这篇博客: 树莓派基于OpenCV的人脸检测和处理中的 一、Windows下使用opencv采集视频 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    1. 属性配置与上一篇相同

    2. 代码

    #include<opencv2\opencv.hpp>
    using namespace cv;
    //========================
    //调用摄像头录像保存
    //==========================
    
    int main() {
    	VideoCapture capture(0);
    	// 设置摄像头的拍摄属性为 分辨率640x480,帧率30fps
    	capture.set(CAP_PROP_FRAME_HEIGHT, 480);
    	capture.set(CAP_PROP_FRAME_WIDTH, 640);
    	capture.set(CAP_PROP_FPS, 30.0);
    	// 设置保存视频的格式为AVI,编码为MJPG
    	VideoWriter writer("chen.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30.0, Size(640, 480), true);
    	Mat videoPlay;
    	// 通过总帧数来控制拍摄时间,如果是10s的段视频的话,循环300次
    	int count(300);
    	namedWindow("VideoPlay", WINDOW_NORMAL);
    	while (count--) {
    		capture >> videoPlay;
    		writer << videoPlay;
    		imshow("VideoPlay", videoPlay);
    		waitKey(1000 / 30);
    	}
    	// 释放相关对象
    	writer.release();
    	capture.release();
    	destroyWindow("VideoPlay");
    	return 0;
    }
    
    1. 视频录制

    在这里插入图片描述
    在这里插入图片描述

  • 您还可以看一下 AI100讲师老师的计算机视觉实战:如何使用OpenCV构建视觉应用课程中的 计算机视觉实战:如何使用OpenCV快速构建视觉应用小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    要解决多摄像头同名问题以获取设备编号,可以通过以下步骤来实现:

    1. 使用 pyglet 库来获取摄像头列表。pyglet 提供了跨平台的音视频库,可以用于获取摄像头设备信息。首先,需要安装 pyglet 库,可以使用以下命令来安装:

    pip install pyglet

    1. 使用以下代码来获取摄像头列表,并打印出每个摄像头的名称和设备编号:

    ```python import pyglet

    def get_camera_device_info(): cameras = pyglet.media.get_video_capture_devices() for i, camera in enumerate(cameras): print(f"Camera #{i + 1}") print(f"Name: {camera.name}") print(f"Device ID: {camera.device}") print()

    if name == "main": get_camera_device_info() ```

    运行上述代码,即可获取摄像头列表以及每个摄像头的名称和设备编号。

    注意:需要在安装 pyglet 库前先安装好对应操作系统的编译依赖库。具体安装方法可以参考 pyglet 官方文档。

    1. 根据需求选择特定的摄像头设备编号来打开摄像头。根据摄像头的设备编号,可以使用 OpenCV 库来打开指定摄像头接口。OpenCV 提供了 cv2.VideoCapture() 函数用于打开摄像头。以下是使用设备编号为 0 的摄像头的示例代码:

    ```python import cv2

    def open_camera(device_id): cap = cv2.VideoCapture(device_id) if not cap.isOpened(): print("Failed to open camera") return

       while True:
           ret, frame = cap.read()
           if ret:
               # 处理摄像头图像帧
               cv2.imshow("Camera", frame)
    
           if cv2.waitKey(1) == ord("q"):
               break
    
       cap.release()
       cv2.destroyAllWindows()
    

    if name == "main": device_id = 0 # 根据摄像头的设备编号来修改 open_camera(device_id) ```

    运行上述代码,即可打开设备编号为 0 的摄像头并显示摄像头的图像。

    注意:如果需要打开其它摄像头的设备编号,只需将 device_id 修改为对应的值即可。

    通过以上步骤,你就可以解决在Windows系统下多摄像头同名问题,并获取摄像头的设备编号以便在OpenCV中打开指定摄像头接口的问题。