opencv+directshow实现4个摄像头同步采集图像 您所在的位置:网站首页 摄像头怎么采集图像 opencv+directshow实现4个摄像头同步采集图像

opencv+directshow实现4个摄像头同步采集图像

2023-12-26 18:04| 来源: 网络整理| 查看: 265

基于网上许多人说到opencv打不开4个摄像头,事实果真如此么,记得哦:opencv是开源的,所以本作者我利用vs2013自己配置了一下opencv与directshow的开发环境,具体要怎么配置我就不详细讲了,上网搜一下就能找得到了,下面我详细讲一下如何将mfc和多线程与opencv和directshow结合实现4个摄像头同步采集图像,本作者正读大二,能力有限,有更好的方法也告诉我一下哈。

一.先在mfc上把界面先布局好如下图

打开4个摄像头

将布局好的界面稍微改一下相关的属性值

这里写图片描述

1-1将显示摄像头区域的ID分别改为: IDC_Camera1 IDC_Camera2 IDC_Camera3 IDC_Camera3

1-2将控制摄像头开关和关闭界面的控件ID分别改为: IDC_Capture1 IDC_Capture2 IDC_Capture3 IDC_Capture4 IDCANCEL

二.在对话框的头文件里添加4个线程句柄和打开4个摄像头和一个关闭界面的响应函数: 这里写图片描述

//创建4个线程句柄 protected: HANDLE h1; HANDLE h2; HANDLE h3; HANDLE h4; // 创建打开摄像头和关闭界面的映射函数 public: afx_msg void OnBnClickedCancel(); afx_msg void OnBnClickedCapture1(); afx_msg void OnBnClickedCapture2(); afx_msg void OnBnClickedCapture3(); afx_msg void OnBnClickedCapture4();

三.在对话框的.cpp文件里的OnInitDialog()函数内初始化句柄

3.1定义一些全局变量来获取图片的句柄 这里写图片描述

//定义一些全局变量来获取图片的句柄 CRect rect1; CRect rect2; CRect rect3; CRect rect4; CDC* pDC1; CDC* pDC2; CDC* pDC3; CDC* pDC4; HDC hDC1; HDC hDC2; HDC hDC3; HDC hDC4; CWnd* pwnd1; CWnd* pwnd2; CWnd* pwnd3; CWnd* pwnd4;

3.2OnInitDialog()函数内初始化句柄 这里写图片描述

//句柄的初始化 pwnd1 = GetDlgItem(IDC_Camera1); pDC1 = pwnd1->GetDC(); hDC1 = pDC1->GetSafeHdc(); pwnd1->GetClientRect(&rect1); pwnd2 = GetDlgItem(IDC_Camera2); pDC2 = pwnd2->GetDC(); hDC2 = pDC2->GetSafeHdc(); pwnd2->GetClientRect(&rect2); pwnd3 = GetDlgItem(IDC_Camera3); pDC3 = pwnd3->GetDC(); hDC3 = pDC3->GetSafeHdc(); pwnd3->GetClientRect(&rect3); pwnd4 = GetDlgItem(IDC_Camera4); pDC4 = pwnd4->GetDC(); hDC4 = pDC4->GetSafeHdc(); pwnd4->GetClientRect(&rect4);

四.在对话框源文件里填加4个互斥对象并添加对应的响应函数: 这里写图片描述

HANDLE hMutex1; //互斥对象1 CCameraDS camera1;//摄像头1 unsigned long _stdcall ThreadProc1(void* IpParameter){ while (1){ WaitForSingleObject(hMutex1, INFINITE);//等待互斥对象所以权 if (CCameraDS::CameraCount() >= 1) { camera1.OpenCamera(0, false, 320, 240);//打开第一个摄像头 while (1) { IplImage *pFrame1 = camera1.QueryFrame();//获取每一帧 CvvImage m_CvvImage; m_CvvImage.CopyOf(pFrame1, 1); if (true) { m_CvvImage.DrawToHDC(hDC1, &rect1);//将获取到的图像画到控件上 } } } else { AfxMessageBox("无法打开摄像头1"); return -1; } Sleep(100); ReleaseMutex(hMutex1); } return 0; } void CDirectshow_4CameraDlg::OnBnClickedCapture1() { CString Text; GetDlgItem(IDC_Capture1)->GetWindowText(Text); //获取按键文本 if (Text == "摄像头1") //判断是否要打开摄像头 { h1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);//创建一个线程 hMutex1 = CreateEvent(NULL, FALSE, TRUE, "event1"); hMutex1 = CreateMutex(NULL, false, "hMutex1"); GetDlgItem(IDC_Capture1)->SetWindowText("关闭摄像头1"); } else //当按键文本为"关闭摄像头1"时,执行关闭摄像头 { TerminateThread(h1, 0); //终止线程1 camera1.CloseCamera(); //关闭摄像头 GetDlgItem(IDC_Capture1)->SetWindowText("摄像头1");//修改按键文本 } } //以下内容相同,省略注释 //摄像头2 HANDLE hMutex2; CCameraDS camera2; unsigned long _stdcall ThreadProc2(void* IpParameter){ while (1){ WaitForSingleObject(hMutex2, INFINITE); if (CCameraDS::CameraCount() >= 2){ camera2.OpenCamera(1, false, 320, 240); while (1) { IplImage *pFrame2 = camera2.QueryFrame(); CvvImage m_CvvImage2; m_CvvImage2.CopyOf(pFrame2, 1); if (true) { m_CvvImage2.DrawToHDC(hDC2, &rect2); } } } else { AfxMessageBox("无法打开摄像头2"); return -1; } Sleep(100); ReleaseMutex(hMutex2); } return 0; } void CDirectshow_4CameraDlg::OnBnClickedCapture2() { CString Text; GetDlgItem(IDC_Capture2)->GetWindowText(Text); if (Text == "摄像头2") { h2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL); hMutex2 = CreateEvent(NULL, FALSE, TRUE, "event2"); hMutex2 = CreateMutex(NULL, false, "hMutex2"); GetDlgItem(IDC_Capture2)->SetWindowText("关闭摄像头2"); } else { TerminateThread(h2, 0); camera2.CloseCamera(); GetDlgItem(IDC_Capture2)->SetWindowText("摄像头2"); } } //摄像头3 HANDLE hMutex3; CCameraDS camera3; unsigned long _stdcall ThreadProc3(void* IpParameter){ while (1){ WaitForSingleObject(hMutex3, INFINITE); if (CCameraDS::CameraCount() >= 3){ camera3.OpenCamera(2, false, 320, 240); while (1) { IplImage *pFrame3 = camera3.QueryFrame(); CvvImage m_CvvImage3; m_CvvImage3.CopyOf(pFrame3, 1); if (true) { m_CvvImage3.DrawToHDC(hDC3, &rect3); } } } else { AfxMessageBox("无法打开摄像头3"); return -1; } Sleep(100); ReleaseMutex(hMutex3); } return 0; } void CDirectshow_4CameraDlg::OnBnClickedCapture3() { CString Text; GetDlgItem(IDC_Capture3)->GetWindowText(Text); if (Text == "摄像头3") { h3 = CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL); hMutex3 = CreateEvent(NULL, FALSE, TRUE, "event3"); hMutex3 = CreateMutex(NULL, false, "hMutex3"); GetDlgItem(IDC_Capture3)->SetWindowText("关闭摄像头3"); } else { TerminateThread(h3, 0); camera3.CloseCamera(); GetDlgItem(IDC_Capture3)->SetWindowText("摄像头3"); } } //摄像头4 HANDLE hMutex4; CCameraDS camera4; unsigned long _stdcall ThreadProc4(void* IpParameter){ while (1){ WaitForSingleObject(hMutex4, INFINITE); if (CCameraDS::CameraCount() >= 4){ CCameraDS camera4; camera4.OpenCamera(3, false, 320, 240); while (1) { IplImage *pFrame4 = camera4.QueryFrame(); CvvImage m_CvvImage4; m_CvvImage4.CopyOf(pFrame4, 1); if (true) { m_CvvImage4.DrawToHDC(hDC4, &rect4); } } } else { AfxMessageBox("无法打开摄像头4"); return -1; } Sleep(100); ReleaseMutex(hMutex4); } return h4 = CreateThread(NULL, 0, ThreadProc4, NULL, 0, NULL); hMutex4 = CreateEvent(NULL, FALSE, TRUE, "event4"); hMutex4 = CreateMutex(NULL, false, "hMutex4"); GetDlgItem(IDC_Capture4)->SetWindowText("关闭摄像头4"); } else { TerminateThread(h4, 0); camera4.CloseCamera(); GetDlgItem(IDC_Capture4)->SetWindowText("摄像头4"); } } pture4)->SetWindowText("关闭摄像头4"); } else { TerminateThread(h4, 0); camera4.CloseCamera(); GetDlgItem(IDC_Capture4)->SetWindowText("摄像头4"); } } void CDirectshow_4CameraDlg::OnBnClickedCancel() { switch (CCameraDS::CameraCount()) //判断需要终止多少个线程 { case 1: { TerminateThread(h1, 0); break; } case 2: { TerminateThread(h1, 0); TerminateThread(h2, 0); break; } case 3: { TerminateThread(h1, 0); TerminateThread(h2, 0); TerminateThread(h3, 0); break; } case 4: { TerminateThread(h1, 0); TerminateThread(h2, 0); TerminateThread(h3, 0); TerminateThread(h4, 0); break; } } CDialogEx::OnCancel(); }

五.验证效果 这里写图片描述

六.总结 opencv+directshow打开4个摄像头的方法除了用互斥对象实现多线程同步外还可以用事件对象实现多线程同步

转载请标明出处:http://blog.csdn.net/lwqbrell/article/details/53954795



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有