通过Opencv打开指定摄像头的方法

这篇具有很好参考价值的文章主要介绍了通过Opencv打开指定摄像头的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们使用Opencv打开摄像头,一般是使用VideoCapture的open接口。

CV_WRAP virtual bool open(int index);

open接口要传入一个标识符,如果只有1个摄像机,那么就是0,如果系统中有多个摄像机,那么只要将其向上增加即可。

系统:

银河麒麟linux系统

问题:

现在我插入了一个双目摄像头(两个USB线,一个彩色,一个红外),那我就想打开彩色的,怎么办呢?每次我插入USB线,系统都会默认给设备分配一个video路径,例如 /dev/video3,根据插入USB线的顺序,每次分配的都不一样,这样通过open就不能指定打开哪一个。

解决思路:

每个设备都有自己的pid和vid,我要通过pid和vid找到特定的/dev/video,例如我获取到了路径 /dev/video3,那么取最后的数字3,通过open(3),即可打开指定的摄像头。需要使用libudev。

下面的函数是通过遍历所有的视频设备,再用摄像头的pid和vid与其对比,最后得到摄像头的路径。(这里注意麒麟linux和UOS系统,打开的序号可能会相差1,所以UOS系统需要可能要再-1)

int findCameraVideoPath(char *pid, char *vid, char *dpath)
{
  struct udev *udev = NULL;
  struct udev_enumerate *udev_enumerate = NULL;
  struct udev_list_entry *list_entry = NULL;
  int count = 0;
  int flag = 0;
  char devName[128]={0};

  udev = udev_new();
  if(udev == NULL)
  {
	//tips
    return 0;
  }
  udev_enumerate = udev_enumerate_new(udev);
  if(udev_enumerate == NULL)
  {
	//tips
    return 0;
  }

  udev_enumerate_add_match_subsystem(udev_enumerate, "video4linux");
  udev_enumerate_scan_devices(udev_enumerate);
  udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate))
 {
    struct udev_device *device;
    device = udev_device_new_from_syspath(udev_enumerate_get_udev(udev_enumerate), udev_list_entry_get_name(list_entry));
    if(device!=NULL)
    {
		//tips
            );

    if(udev_device_get_property_value(device, "ID_VENDOR_ID")!=NULL &&
           udev_device_get_property_value(device, "ID_MODEL_ID")!=NULL &&
           !strcmp(vid, udev_device_get_property_value(device, "ID_VENDOR_ID")) &&
           !strcmp(pid, udev_device_get_property_value(device, "ID_MODEL_ID")))
        {
        sprintf(devName,"/dev/video%s", udev_device_get_sysnum(device));
                flag = 1;
        count++;
        }
    udev_device_unref(device);

    }
    else
    {
        //tips
    }
  }

   if(flag!=0)
   {
      if(strlen(devName)>0)
        memcpy(dpath, devName, strlen(devName));
   }

    udev_enumerate_unref(udev_enumerate);
    udev_unref(udev);

    return flag;
}

下面附上win系统MFC的事例,与上面思路类似:文章来源地址https://www.toymoban.com/news/detail-539196.html

#include <iostream>
#include <string>
#include <vector>
#include <DShow.h>
#include <CString>
#pragma   comment(lib,"Strmiids.lib")

using namespace std;
//输入:pidvid     exp: vid_1234&pid_1234
//输出:ID, 为-1则找不到设备
int getCamIDFromPidVid(char* pidvid)
{
	int iRet = -1;
	int iCameraNum = 0;			//设备个数
	vector<CString> devList;	//设备列表

	CString str ;
    ICreateDevEnum *pDevEnum = NULL;
    IEnumMoniker *pEnum = NULL;
    HRESULT hr = NULL;
    CoInitialize(NULL);
	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;
            ULONG cFetched;
			while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK)
			{
				IPropertyBag* pPropBag;
                hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,reinterpret_cast<void**>(&pPropBag));  
				if (SUCCEEDED(hr))
				{
					//获取设备路径,路径里包含pidvid的信息
                    VARIANT varName;
                    varName.vt = VT_BSTR;
                    VariantInit(&varName);
                    hr = pPropBag->Read(L"DevicePath", &varName, 0);		//read函数只能够读取CLSID, FriendlyName, DevicePath这三种

                    CString sdev(varName);
                    devList.push_back(sdev);

                    iCameraNum   ++;
                    pPropBag->Release();
				}

				pMoniker->Release();
			}
		}
	}

	//对比,得到id
	for(int i = 0;i<devList.size();i++)
	{
		int index = devList[i].Find(pidvid);
		if(index != -1)
		{
			iRet = i;
			break;
		}
	}

	CoUninitialize();
	return iRet;
}

到了这里,关于通过Opencv打开指定摄像头的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 4.通过Opencv采集摄像头视频数据

    VideoCapture() 虚拟采集器,一般设备号从0开始 cap.read() 读取视频帧 返回值有两个,第一个为状态值,读到帧为true 第二个值为视频帧 cap.release() 释放资源 示例程序: 运行结果: 从视频文件中读取视频帧 只处理视频,不处理音频,所以读取到的视频没有声音 播放速度设置 Vi

    2023年04月22日
    浏览(41)
  • opencv进阶09-视频处理cv2.VideoCapture示例(打开本机电脑摄像头)

    视频信号(以下简称为视频)是非常重要的视觉信息来源,它是视觉处理过程中经常要处理的一类信号。实际上,视频是由一系列图像构成的,这一系列图像被称为帧,帧是以固定的时间间隔从视频中获取的。获取(播放)帧的速度称为帧速率,其单位通常使用“帧/秒”表示

    2024年02月12日
    浏览(48)
  • jetson nano USB摄像头使用openCv打开帧率低的问题

    最近玩jetson nano的时候发现openCv打开USB摄像头帧率只有5帧,但是windows下能跑30帧,在网络搜了一下原因发现是摄像头默认读取格式不对,需要改成MJPG格式帧率才能上去,于是使用CSDN上找的代码,但是都不能工作,折腾了好久没搞定,突然想到上 stacoverflow上看看,没想到真的

    2024年02月06日
    浏览(116)
  • 解决树莓派原装libcamera(csi)摄像头无法通过opencv读取数据的问题

    1.1 硬件 树莓派4B 树莓派原装CSI摄像头IMX219(libcamera Camera Raspberry Pi) 1.2 软件 64位树莓派arrch64,Debian 11(bullseye) Python3.9 OpenCv 此时返回的ret,frame = (False, None) 继续执行下面这条语句 报错如下 若直接执行 则报错如下 出现上述情况,应该是opencv读取不到摄像头数据所致 接下来排

    2024年02月03日
    浏览(41)
  • WSL2通过OpenCV调用并展示本机摄像头的RTSP视频流

    本篇博客的由来如上图哈哈,WSL2 相关安装教程可以参考我之前的博客:Win11安装WSL2和Nvidia驱动 更多文章欢迎来我的博客小站看呀,会有更多的技术细节~ ubuntu上请执行 或者编译安装 如果报错 Could NOT find OpenSSL ,安装如下依赖即可解决 下载解压 EasyDarwin Easydarwin是国内团队开

    2024年02月09日
    浏览(71)
  • opencv基础: 视频,摄像头读取与保存的常用方法

    当然还可以从视频中抓取截图,所以现在聊一下常用的抓取视频截图的的方法。 上面有三种构造方法, 第一种是无法构造方法。 第二种参数device是一个数字。 一般笔记本如此写cv2.VideoCapture(0); 因为默认是0 ,如果有多个摄像头,就需要看设置的摄像头代表的数字了。 第二种

    2024年02月09日
    浏览(39)
  • OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、

    2024年03月13日
    浏览(44)
  • OpenCV读取摄像头窗口变大且很卡的解决方法

    OpenCV读取摄像头窗口变大且很卡的解决方法 读取摄像头窗口变大且很卡的代码 运行后,读取摄像头的窗口很大,而且很卡,出现如下的提示 安装libcanberra-gtk-module 继续运行,还是很卡,WARN还在,修改代码如下,增加cv2.CAP_V4L2 v4l2(video for linux two)是Linux中内核提供给应用层

    2024年01月25日
    浏览(53)
  • OpenCV VideoCapture使用方法(视频文件、摄像头、网络视频文件)

    cv::VideoCapture既支持视频文件的读取,也支持从摄像机中视频的读取。cv::VideoCapture对象的创建方式有以下三种: 方式一:     cv::VideoCapture capture(     const string filename, // 输入视频文件路径名     ); 方式二:     cv::VideoCapture capture(     int device // 输入摄像机视频捕捉设备

    2024年02月06日
    浏览(57)
  • 基于opencv第三方视觉库,通过内网IP调用手机摄像头,实现人脸识别与图形监测

    OpenCV 是一个开源的计算机视觉库,OpenCV 库用C语言和 C++ 语言编写,可以在 Windows、Linux、Mac OS X 等系统运行。同时也在积极开发 Python、Java、Matlab 以及其他一些语言的接口,将库导入安卓和 iOS 中为移动设备开发应用。 OpenCV 库包含从计算机视觉各个领域衍生出来的 500 多个函

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包