基于OpenCV 、VS2008 MFC对话框的USB摄像头的控制和视频播放、跟踪(logitech sphere AF网络摄像头)

来源:互联网 发布:网络安全保密教育 编辑:程序博客网 时间:2024/05/22 12:55

基于OpenCV 、VS2008 MFC对话框的USB摄像头的控制和视频播放、跟踪(logitech sphere AF网络摄像头)

 

1.opencv

2.vs2008 mfc

3.logitech sphere AF网络摄像头的pan tilt zoom控制

4.SIR粒子滤波

 

我已经做完了,总结完后上传。

 

 

gui interface

 

草稿

 PTZ Pan, Tilt, Zoom )摄像机跟踪指图像工作站通过对摄像头所获取的视频图像序列处理,对运动目标进行检测、分割和跟踪,将得到的目标偏离视场中心的偏差值反馈给云台,控制其全方位转动,实现摄像机对目标的同步跟踪。

 

1.     界面设计

基于 Visual Studio 2008 MFC 技术, 在对话框GUI 界面,往里面添加若干Button 和一个Picture 控件,如图


2.1 GUI 界面

各个控件的ID 号由Visual C++ 自动产生并存放于Resource.h 文件中,比如其中一句定义:

#define IDC_ShowImg                      1002

定义了图片控件的ID 号,由图片控件显示图片时只需要使用如下命令:

CDC* pDC = GetDlgItem( IDC_ShowImg)->GetDC();// 获得显示控件的DC

HDC hDC = pDC->GetSafeHdc();   // 获取HDC( 设备句柄) 来进行绘图操作

img.DrawToHDC( hDC, &rect ); // 将图片绘制到显示控件的指定区域内

同时,为了实时显示各种参数,创建了状态栏。

HWND hStatusWindow;

HWND hDlg=GetSafeHwnd();

int IDS_STATUS =1;

hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER,TEXT(" 状态栏"),hDlg, IDS_STATUS);

int pint[4]={110,250,300,-1};//110,250,300 设定间隔

::SendMessage(hStatusWindow,SB_SETPARTS,4,(LPARAM)pint);

在状态栏中,将不断显示水平、垂直转动的角度和焦距变化值,这样可以使用户在使用系统的过程中得到一些关心的准确数据。

2.     人脸检测

人脸检测方法是一种基于积分图、级联检测器和AdaBoost 算法的方法,方法框架可以分为以下三大部分

第一部分,使用Harr-llke 特征表示人脸,使用“积分图’’实现特征数值的快速计算;

第二部分,使用Adaboost 算法挑选出一些最能代表人脸的矩形特征( 弱分类器) ,按照加权投票的方式将弱分类器构造为一个强分类器:

第三部分,将训练得到的若干强分类器串联组成一个级联结构的层叠分类器,级联结构能有效地提高分类器的检测速度。

基于AdaBoost 的人脸检测在OpenCV 中的具体实现步骤如图2.2

 


2.2 OpenCV2.0 实现人脸检测的基本步骤

1)      加载分类器。利用以下语句实现分类器的加载。

static CvHaarClassifierCascade* cascade = 0;

const char* cascade_name ="haarcascade_frontalface_alt.xml";

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

2)       同时,0penCV 在加载的时候将分类器转化成了内部格式。加载检测图像。在本检测中,首先将3 通道8 位的彩色图转为灰度图,然后将灰度图按缩小1.3 倍。

    cvCvtColor( img, gray, CV_BGR2GRAY );// 将彩色图转化为灰度图

cvResize( gray, small_img, CV_INTER_LINEAR );// 将灰度图缩小

3)       检测人脸。通过以下函数实现人脸检测

vSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,

        1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(30, 30) );

通过以下函数得到脸部坐标:

CvRect r = (CvRect*)cvGetSeqElem( faces,0);

 


2.3 人脸检测效果图

3.     基于多线程的视频文件播放

在多线程方法中,同一进程内所有线程共享惟一的进程地址空间资源,线程间共用内存空间、寄存器、进程表项等,不存在通过第三方进行信息交换的问题;而线程内部也能通过线程数据槽等方法实现各自的变量存储,所以多线程技术是并发程序设计方式中最为简单的一种,是首选工具。

在未采用多线程前,单击Capture 按钮,视频播放的过程中整个GUI 界面将失去消息响应,因为视频播放是一个死循环的过程。为了解决这个问题,本系统采用多线程技术,实现了视频播放与主程序的独立。

Button 控件Capture 下添加了void CmymfcDlg::OnBnClickedReadimg() 按钮点击的消息响应程序,在程序中添加如下代码:

        CreateThread(NULL,0,CaptureThread,Capture_param,0,NULL);

创建了一个线程,线程函数为C aptureThread ,传入参数为Capture_param 。在 DWORD WINAPI CaptureThread(LPVOID pParam) 函数中,实现了每帧视频的读取和粒子滤波的循环。

4.     基于OpenCV 2.0 的视频文件读取

OpenCV 是一种用于数字图像处理和计算机视觉的函数库。它由英特尔公司开发,是一套可免费获得的由一些C 函数和C++ 类所组成的库。OpenCVWindows 系统及Linux 系统下都可以使用,它提供了很多标准的图像处理算法,主要用于对图像进行一些高级处理。这些函数可以直接在具体的视频开发项目中调用,通过简单编程即可完成十分复杂庞大的开发任务,具有很好的效率。

CvCapture* pCapture;

pCapture = cvCaptureFromCAM(0) ;

IplImage* ipl=NULL;

ipl = cvQueryFrame( Capture_param->plistener->pCapture );

通过以上代码实现了从摄像头读取每帧图片。由于图片控件的大小是276 ×276 ,需要对摄像头采集的图像进行缩放。摄像头采集的图像大小是320 ×240 ,上下添加黑边至320 ×320, 然后进行256/320 的缩放。

cvSetImageROI( TheImage, cvRect( tlx, tly, nw, nh) );

cvResize( img, TheImage );

cvResetImageROI( TheImage );

通过OpenCV 设置感兴趣区域ROI 进行缩放, 可以很方便地实现图片以合适尺寸显示。

5.     PTZ 摄像头的控制

PTZ.CPP 文件中,主要通过如下函数实现摄像头的控制。

HRESULT set_mechanical_pan_relative(IAMCameraControl *pCameraControl, long value);

HRESULT set_mechanical_tilt_relative(IAMCameraControl *pCameraControl, long value);

以上两个函数,实现了摄像头的水平和垂直转动,输入参数分别为摄像头的ID 号和转动角度。

HRESULT set_digital_zoom_absolute(IAMCameraControl *pCameraControl, long value);

这个函数实现了摄像头的放大缩小倍数。

Logitech 此款摄像头中,焦距的变化范围从50mm200mm 。函数传入的value 即设置的焦距值 。这样可以看到,此摄像头最大的放大倍数是4 倍。

6.     粒子滤波程序的实现

Button 控件track 下添加了void CmymfcDlg:: OnBnClickedTrace () 按钮点击的消息响应程序,在程序中添加如下代码:

if(initPFTracking((PixelsInfor *)ImageSource->imageData,

                                      &TrackLocation,

                                      &goalFeatuerStuctAdr,

                                      &G_MAIN_ParticlesAdr,

                                      G_MAIN_PARNUMBER)!=0)

                   {

                           AfxMessageBox("SIR initialization error!");

                   }

启动粒子滤波程序。

其中TrackLocation 为目标位置,本系统由两种方式输入。

a)      由鼠标响应事件产生

GUI 界面中,添加如下消息响应事件

void CmymfcDlg::OnLButtonDown(UINT nFlags, CPoint point)

void CmymfcDlg::OnLButtonUp(UINT nFlags, CPoint point)

由鼠标画框事件,记录下目标的坐标,再传给粒子滤波初始化程序。

b)    AdaBoost 人脸检测程序的返回值确定。

人脸检测程序可以返回检测结果,通过一定的换算后可以得到目标位置,然后传递给粒子滤波程序,实现了人脸的自动检测和跟踪。

当初始化完成后,将粒子滤波的初始化完成标志位注为真,然后每帧图像显示前调用如下函数进行持续跟踪并返回位置坐标,画框程序根据位置坐标不断进行标注。

if(oncePFTracking((PixelsInfor *)(ImageSource->imageData),

                               Capture_param->plistener->G_MAIN_ParticlesAdr,                                G_MAIN_PARNUMBER,

                                      Capture_param->plistener->goalFeatuerStuctAdr,

                                      &Capture_param->plistener->TrackLocation)!=0)

        {

                       AfxMessageBox("tracking code error!");}

总结

本系统在VS2008 下开发环境下,开发出了基于MFC 对话框的人机交互界面,使用OpenCV 2.0 函数库和多线程技术,在流畅播放视频的同时,能进行基于用户操作的Logitech USB 摄像头的PTZ 控制,能自动运行基于Adaboost 的人脸检测并具有非常高的准确性,能提供两种目标输入模式的粒子滤波程序的人脸跟踪,并能根据跟踪结果对摄像头进行水平、垂直控制,使跟踪实现了水平360 , 垂直90 的跟踪效果。

本系统只是完成了水平和垂直的转动跟踪,没有使云台根据转动参数实现目标跟踪过程中的自动镜头缩放,这个是下一步需要继续深入下去的工作。

 

五 部分代码

回答一个朋友的问题

1.怎么交换数据?

在窗体初始化的时候,创建守护线程,在守护线程中不断获取图像,并通过MFC显示。通过函数调用传递参数,不会产生延时。

以下代码是Capture_param的定义

以下是显示代码



 

原创粉丝点击