在MFC对话框的控件中显示Opencv摄像头视频+Camshift跟踪算法实现
- 格式:doc
- 大小:150.50 KB
- 文档页数:3
开摄像头的按钮,一个关闭摄像头的按钮。
有一个PictureBox的控件。
1.CvCapture* capture;2.CRect rect;3.CDC *pDC;4.HDC hDC;5.CWnd *pwnd;这里特别注意,这些变量一定要是全局变量。
再来看一下这些变量的添加位置:[cpp]view plaincopyprint?1.#include "stdafx.h"2.#include "VideoMFC.h"3.#include "VideoMFCDlg.h"4.#include "afxdialogex.h"5.6.#ifdef _DEBUG7.#define new DEBUG_NEW8.#endif9.10.11.CvCapture* capture;12.CRect rect;13.CDC *pDC;14.HDC hDC;15.CWnd *pwnd;16.17.// CAboutDlg dialog used for App About18.19.class CAboutDlg : public CDialogEx20.{21.public:然后在窗口的初始化函数中进行句柄的初始化:[cpp]view plaincopyprint?1.OnInitDialog()这个函数,BOOL CVideoMFCDlg::OnInitDialog()初始化代码:[cpp]view plaincopyprint?1.// CVideoMFCDlg message handlers2.3.BOOL CVideoMFCDlg::OnInitDialog()4.{5. CDialogEx::OnInitDialog();6.7. // Add "About..." menu item to system menu.8.9. // IDM_ABOUTBOX must be in the system command range.10. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);11. ASSERT(IDM_ABOUTBOX < 0xF000);12.13. CMenu* pSysMenu = GetSystemMenu(FALSE);14. if (pSysMenu != NULL)15. {16.BOOL bNameValid;17. CString strAboutMenu;18. bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);19. ASSERT(bNameValid);20. if (!strAboutMenu.IsEmpty())21. {22. pSysMenu->AppendMenu(MF_SEPARATOR);23. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);24. }25. }26.27.28. // Set the icon for this dialog. The framework does this automatically29. // when the application's main window is not a dialog30. SetIcon(m_hIcon, TRUE); // Set big icon31. SetIcon(m_hIcon, FALSE); // Set small icon32.33. // TODO: Add extra initialization here34. pwnd = GetDlgItem(IDC_ShowImage);35. //pwnd->MoveWindow(35,30,352,288);36. pDC =pwnd->GetDC();37. //pDC =GetDC();38. hDC= pDC->GetSafeHdc();39. pwnd->GetClientRect(&rect);40.41.42.43. return TRUE; // return TRUE unless you set the focus to a control44.}这里的初始化代码只有Todo后面的是自己添加的,目的是获得图像控件的句柄,将来好在上面显示图像。
Visual Studio2010在MFC中用opencv实现对视频中动态目标的追踪第二步,建立一个MFC的对话框程序,做两个按钮,一个“打开视频文件”,一个“运动跟踪处理”。
具体操作:1 建立MFC对话框程序的框架:File ->New -> MFC AppWizard(exe),选取工程路径,并取工程名“VideoProcesssing”-> Next -> 选择Dialog based后,去掉使用Unicode库的勾,选择在静态库中使用 MFC,点Finish,点OK.2 添加按钮:直接Delete掉界面默认的两个“确定”“取消”按钮。
然后添加两个button,分别名为“打开视频”,“运动跟踪处理”,其ID分别设为IDC_OPEN_VIDEO,IDC_TRACKING.3 添加消息响应函数:双击按钮“打开视频文件”,自动生成响应函数名OnOpenVideo,点Ok。
然后添加如下代码:CFileDialog dlg(true,"*.avi",NULL,NULL,"*.avi|*.avi||");if (dlg.DoModal()==IDOK){strAviFilePath = dlg.GetPathName();}else{return;}同样,双击“运动跟踪处理”按钮,选择默认的响应函数名,然后添加代码://声明IplImage指针IplImage* pFrame = NULL;IplImage* pFrImg = NULL;IplImage* pBkImg = NULL;CvMat* pFrameMat = NULL;CvMat* pFrMat = NULL;CvMat* pBkMat = NULL;CvCapture* pCapture = NULL;int nFrmNum = 0;//打开AVI视频文件if(strAviFilePath=="") //判断文件路径是否为空{MessageBox("请先选择AVI视频文件!");return;}else{if(!(pCapture = cvCaptureFromFile(strAviFilePath))) {MessageBox("打开AVI视频文件失败!");return;}}//创建窗口cvNamedWindow("Video", 1);cvNamedWindow("Background",1);cvNamedWindow("Foreground",1);//使窗口有序排列,窗口宽330cvMoveWindow("Video", 30, 0);cvMoveWindow("Background", 360, 0);cvMoveWindow("Foreground", 690, 0);//逐帧读取视频while(pFrame = cvQueryFrame( pCapture )){nFrmNum++;//如果是第一帧,需要申请内存,并初始化if(nFrmNum == 1){pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1); // 存放背景图像(灰度)pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1); // 存放中间图像(灰度)pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//转化成单通道图像再处理(灰度)cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);cvConvert(pFrImg, pFrameMat);cvConvert(pFrImg, pFrMat);cvConvert(pFrImg, pBkMat);}else{cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); //转化成单通道图像再处理(灰度)cvConvert(pFrImg, pFrameMat);//高斯滤波先,以平滑图像//cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);//当前帧跟背景图相减(求背景差并取绝对值)cvAbsDiff(pFrameMat, pBkMat, pFrMat);//二值化前景图(这里采用特定阈值进行二值化)cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);//进行形态学滤波,去掉噪音cvErode(pFrImg, pFrImg, 0, 1);cvDilate(pFrImg, pFrImg, 0, 1);//滑动平均更新背景(求平均)cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);//将背景转化为图像格式,用以显示cvConvert(pBkMat, pBkImg);// 保持原图像的旋转方向pBkImg->origin = pFrImg->origin = pFrame->origin;//显示图像cvShowImage("Video", pFrame);cvShowImage("Background", pBkImg);cvShowImage("Foreground", pFrImg);//如果有按键事件,则跳出循环//此等待也为cvShowImage函数提供时间完成显示//等待时间可以根据CPU速度调整if( cvWaitKey(200) >= 0 )break;}}//销毁窗口cvDestroyWindow("Video");cvDestroyWindow("Background");cvDestroyWindow("Foreground");//释放图像和矩阵cvReleaseImage(&pFrImg);cvReleaseImage(&pBkImg);cvReleaseMat(&pFrameMat);cvReleaseMat(&pFrMat);cvReleaseMat(&pBkMat);cvReleaseCapture(&pCapture);4 选fileview选项卡中VideoProcessingDlg.h,在CVideoProcessingDlg类中添加公有类成员:CString strAviFilePath;5 选fileview选项卡中VideoProcessingDlg.cpp,添加opencv头文件#include "cv.h"#include "highgui.h"#include "cxcore.h"6 编译执行,成功!还可以添加一个”录制视频”的按钮,修改ID号为IDC_RECORD,双击“录制视频”按钮,选择默认的响应函数名,然后添加代码:CvCapture* capture=cvCaptureFromCAM(-1); //打开摄像头CvVideoWriter* video=NULL;IplImage* frame=NULL;int n;if(!capture) //如果不能打开摄像头给出警告{cout<<"Can not open the camera."<<endl;return ;}else{frame=cvQueryFrame(capture); //首先取得摄像头中的一帧video=cvCreateVideoWriter("camera.avi", CV_FOURCC('X', 'V', 'I', 'D'), 25,cvSize(frame->width,frame->height)); //创建CvVideoWriter对象并分配空间//保存的文件名为camera.avi,编码要在运行程序时选择,大小就是摄像头视频的大小,帧频率是32if(video) //如果能创建CvVideoWriter对象则表明成功{cout<<"VideoWriter has created."<<endl;}cvNamedWindow("Camera Video",1); //新建一个窗口int i = 0;while(i <= 200) // 让它循环200次自动停止录取{frame=cvQueryFrame(capture); //从CvCapture中获得一帧if(!frame){cout<<"Can not get frame from the capture."<<endl;break;}n=cvWriteFrame(video,frame); //判断是否写入成功,如果返回的是1,表示写入成功cout<<n<<endl;cvShowImage("Camera Video",frame); //显示视频内容的图片i++;if(cvWaitKey(2)>0)break; //有其他键盘响应,则退出}cvReleaseVideoWriter(&video);cvReleaseCapture(&capture);cvDestroyWindow("Camera Video");}return ;第二步,建立一个编程环境,然后加载opencv的库路径等等。
基于OpenCV的实时图像处理与识别在当今数字化、智能化的时代下,图像处理和识别技术变得越来越重要。
OpenCV是一个常用的开源的计算机视觉库,它提供了许多用于图像处理和分析的函数和算法。
本文将介绍如何使用OpenCV来实现基于摄像头实时图像处理和识别。
一、准备工作首先,我们需要安装和配置OpenCV库,以便能够在Python中使用。
具体可以参考官网的安装指南。
安装完成后,引入库,并测试是否能够正常使用。
二、使用摄像头获取图像在进行图像处理和识别之前,首先需要获取摄像头实时生成的图像。
```import cv2cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()cv2.imshow("Video", frame)if cv2.waitKey(1) & 0xFF == ord("q"):breakcap.release()cv2.destroyAllWindows()```在上面的代码中,我们使用`cv2.VideoCapture(0)`函数打开摄像头。
其中参数`0`表示默认使用第一个摄像头,如果有多个摄像头,可以使用不同的数字来切换。
通过`cap.read()`函数读取摄像头返回的视频帧,`ret`表示读取是否成功,`frame`表示读取到的视频帧。
将读取到的视频帧通过`cv2.imshow()`函数显示在窗口中,通过`cv2.waitKey()`函数等待用户键盘输入,输入`q`表示退出程序。
最后,通过`cap.release()`函数释放资源,关闭窗口。
运行程序后,我们可以看到摄像头实时获取到的图像。
三、实现图像处理功能在获取摄像头实时生成的图像后,我们可以对图像进行一些处理,以便后续进行识别。
1. 图像灰度处理将彩色图像转换成灰度图像是进行图像处理的第一步。
通过OpenCV中的`cv2.cvtColor()`函数实现。
mfc中picture control使用在MFC中,Picture Control是一个用于显示图片的用户界面控件。
它通常用于在应用程序中展示图像内容。
以下是使用MFC中的Picture Control控件的步骤:1、添加Picture Control控件:在Visual Studio的设计视图中,打开你的对话框资源。
在工具箱中,找到Picture Control 控件并将其拖动到对话框上。
2、关联Picture Control控件与变量:选中Picture Control控件,在属性窗口中找到IDC_STATIC对应的ID,然后将其改为一个唯一的ID,比如IDC_PICTURE。
同时,在Class View中为该控件添加一个对应的变量,类型选择为CStatic。
3、加载并显示图片:在代码中找到对应的消息处理函数(例如OnInitDialog),然后使用以下代码加载并显示图片:cpp// 加载图片资源HRSRC hResource = FindResource(AfxGetResourceHandle(),MAKEINTRESOURCE(IDB_PICTURE), RT_RC);HGLOBAL hGlobal = LoadResource(AfxGetResourceHandle(), hResource);// 获取图片数据的指针LPCTSTR lpData = (LPCTSTR)LockResource(hGlobal);// 计算图片大小DWORD dwSize = SizeofResource(AfxGetResourceHandle(), hResource);// 创建位图对象CBitmap bitmap;bitmap.CreateFromBase(lpData, dwSize, NULL, LR_CREATEDIBSECTION);// 获取Picture Control控件的句柄HWND hWndPicture = GetDlgItem(IDC_PICTURE);// 创建兼容的DC(设备上下文)对象CDC compatibleDC;compatibleDC.CreateCompatibleDC(&compatibleDC);// 创建位图对象兼容的位图CBitmap* pOldBitmap = compatibleDC.SelectObject(&bitmap);// 将位图绘制到Picture Control控件上BitBlt(hWndPicture, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), &compatibleDC, 0, 0, SRCCOPY);// 释放资源compatibleDC.SelectObject(pOldBitmap);FreeResource(hGlobal);上述代码假设你的图片资源已经添加到资源文件中,并且资源的ID为IDB_PICTURE。
基于OpenCV的运动目标跟踪及其实现作者:李振伟陈翀赵有来源:《现代电子技术》2008年第20期摘要:CAMSHIFT算法是一种基于颜色直方图的目标跟踪算法。
在视频跟踪过程中,CAMSHIFT算法利用选定目标的颜色直方图模型得到每帧图像的颜色投影图,并根据上一帧跟踪的结果自适应调整搜索窗口的位置和大小,得到当前帧中目标的尺寸和质心位置。
在介绍Intel公司的开源OpenCV计算机视觉库的基础上,采用CAMSHIFT跟踪算法,实现运动目标跟踪,解决了跟踪目标发生存在旋转或部分遮挡等复杂情况下的跟踪难题。
实验结果表明该算法的有效性、优越性和可行性。
关键词:目标跟踪;CAMSHIFT算法;OpenCV;颜色直方图中图分类号:TP391文献标识码:B文章编号:1004373X(2008)2012803Moving Object Tracking Method and Implement Based on OpenCVLI Zhenwei1,2,CHEN Chong1,2,ZHAO You1(1.Changchun Observatory,National Astronomical Observatories,Chinese Academy of Sciences,Changchun,130117,China;2.Graduate School,Chinese Academy of Sciences,Beijing,100049,China)Abstract:CAMSHIFT is an object tracking algorithm based onthe color histogram.In the process of object tracking,CAMSHIFT operates on a color back-projection image produced from object histogram model in current frame and finds the location and size of the current frame by adaptively adjusting the size and the location of the searching windows according to the tracking results of the previous frame in the video.On the basis of introducing OpenCV(an Intel open source computer vision library),through CAMSHIFT algorithm,the paper realizes moving object tracking and resolves some problems including distractor and occlusion by other objects.Experimental results show good perf o rmances,superiority and feasibility of the algorithm.Keywords:object tracking;CAMSHIFT algorithm;OpenCV;color histogram目标跟踪是计算机视觉的一个重要分支,日益广泛应用于科学技术、国防安全、航空、医药卫生以及国民经济等领域。
物体跟踪算法在视频监控中的应用教程随着科技的不断发展,视频监控技术的应用越来越广泛。
而为了更好地保障安全,实时的物体跟踪算法变得尤为重要。
本篇文章将为您介绍物体跟踪算法在视频监控中的应用以及相关的教程。
一、物体跟踪算法的概述物体跟踪是指通过对视频序列进行分析和处理,实时地追踪感兴趣的物体。
它涉及到图像处理、计算机视觉和机器学习等领域的技术。
物体跟踪算法在视频监控中的应用非常广泛,包括人脸跟踪、车辆跟踪等。
二、视频监控中的常用物体跟踪算法1. 卡尔曼滤波器(Kalman Filter)算法卡尔曼滤波器算法是一种递归估计算法,常用于预测和估计物体的位置。
它通过不断地更新位置估计值,可以在一定程度上解决物体漂移和遮挡等问题。
卡尔曼滤波器算法在实时视频监控中应用广泛,特别适用于移动目标的跟踪。
2. 均值漂移(Mean Shift)算法均值漂移算法是一种非参数化的密度估计算法,在物体跟踪中有着广泛的应用。
它通过不断地调整搜索窗口的中心,寻找最大密度值所在的位置,从而实现物体的跟踪。
均值漂移算法对物体颜色模型的准确性要求较高,在处理光照变化和背景干扰时比较强大。
3. CamShift 算法CamShift 算法基于均值漂移算法,是一种自适应的物体跟踪算法。
它通过不断地更新搜索窗口的大小和方向来跟踪目标物体。
相比于均值漂移算法,CamShift 算法对于光照变化和尺度变化较为稳健,常用于人脸跟踪和手势识别等应用。
4. Haar 级联检测器Haar 级联检测器是一种基于机器学习的物体检测和跟踪算法。
它使用Haar 特征和 AdaBoost 训练算法来实现目标物体的检测和跟踪。
Haar 级联检测器对于人脸、行人等物体有着较好的效果,并且具有较高的计算效率。
三、物体跟踪算法在视频监控中的应用教程下面将介绍物体跟踪算法在视频监控中的应用教程,涵盖了卡尔曼滤波器、均值漂移和 Haar 级联检测器三种算法的基本原理和实现方法。
opencv videocapture的实现原理-回复OpenCV是一个开源的计算机视觉库,提供了许多用于图像和视频处理的功能。
其中,VideoCapture是OpenCV中的一个类,用于从摄像头或视频文件中捕获帧。
本文将介绍VideoCapture的实现原理,并逐步解释其工作流程。
1. 寻找摄像头或打开视频文件在使用VideoCapture之前,我们需要先调用它的构造函数,创建一个VideoCapture对象。
构造函数允许我们指定要捕获的设备索引或视频文件路径。
当指定的设备或文件不存在时,VideoCapture将返回一个空对象。
2. 初始化视频流一旦成功打开摄像头或视频文件,VideoCapture会尝试初始化视频流。
它首先读取视频的头部信息,包括分辨率、帧率和编解码器信息。
这些信息对于后续的视频处理非常重要,因为它们决定了如何解释视频流数据。
3. 循环读取帧一旦视频流被成功初始化,VideoCapture就开始进入一个循环,用于读取视频的每一帧。
它会读取下一帧的图像数据,并将其存储在内存中供后续处理使用。
4. 检查视频流是否结束在读取每一帧之前,VideoCapture会检查视频流是否已经结束。
如果视频流已经结束,它会跳出循环并关闭流。
5. 存储帧数据读取成功的帧数据将被存储在内存中,通常是一个图像矩阵或一个视频帧对象。
这个数据结构允许我们进行进一步的图像处理,例如检测对象、应用滤波器或进行特征提取。
6. 解码帧数据在存储帧数据之后,VideoCapture会将其解码为常用的图像格式,例如BGR或灰度。
这样,我们就可以在处理帧数据之前,先进行图像格式转换或颜色空间转换。
7. 处理帧数据一旦帧数据被解码并存储在内存中,我们可以使用OpenCV的其他功能来对其进行处理。
例如,我们可以在图像上应用滤波器、边缘检测、目标检测等。
8. 显示或保存帧数据处理完帧数据后,我们可以选择将其显示在屏幕上或保存到本地文件中。
主要基于两种思路:a)不依赖于先验知识,直接从图像序列中检测到运动目标,并进行目标识别,最终跟踪感兴趣的运动目标;b)依赖于目标的先验知识,首先为运动目标建模,然后在图像序列中实时找到相匹配的运动目标。
一.运动目标检测对于不依赖先验知识的目标跟踪来讲,运动检测是实现跟踪的第一步。
运动检测即为从序列图像中将变化区域从背景图像中提取出来。
运动目标检测的算法依照目标与摄像机之间的关系可以分为静态背景下运动检测和动态背景下运动检测〔一〕静态背景1.背景差2.帧差3.GMM4.光流背景减算法可以对背景的光照变化、噪声干扰以及周期性运动等进行建模,在各种不同情况下它都可以准确地检测出运动目标。
因此对于固定摄像头的情形,目前大多数的跟踪算法中都采用背景减算法来进行目标检测。
背景减算法的局限性在于它需要一个静态的固定摄像头。
〔二〕运动场通常情况下,摄像机的运动形式可以分为两种:a)摄像机的支架固定,但摄像机可以偏转、俯仰以及缩放; b)将摄像机装在某个移动的载体上。
由于以上两种情况下的背景及前景图像都在做全局运动,要准确检测运动目标的首要任务是进行图像的全局运动估计与补偿。
考虑到图像帧上各点的全局运动矢量虽不尽相同(摄像机做平移运动除外),但它们均是在同一摄像机模型下的运动,因而应遵循相同的运动模型,可以用同一模型参数来表示。
全局运动的估计问题就被归结为全局运动模型参数的估计问题,通常使用块匹配法或光流估计法来进行运动参数的估计。
块匹配基于块的运动估算和补偿可算是最通用的算法。
可以将图像分割成不同的图像块,假定同一图像小块上的运动矢量是相同的,通过像素域搜索得到最正确的运动矢量估算。
块匹配法主要有如下三个关键技术:a)匹配法则,如最大相关、最小误差等b)搜索方法,如三步搜索法、交叉搜索法等。
c) 块大小确实定,如分级、自适应等。
光流法光流估计的方法都是基于以下假设:图像灰度分布的变化完全是目标或者场景的运动引起的,也就是说,目标与场景的灰度不随时间变化。
在MFC对话框的控件中显示Opencv摄像头视频+Camshift跟踪算法实现
2010-05-07 16:31
一般用opencv显示视频,都用cvNamedWindow新建窗口,并且在while循环中更新每一帧视频,由于窗口是opencv自己创建的,所以在VC中很难对其进行控制,出于这个目的,希望能将视频显示在VC能够控制的部件中。
这里给出一个实例说明如何在MFC对话框的picture控件中显示摄像头视频。
主要步骤为:
1.建立对话框工程并设置对话框布局
注意对话框中间的是picture控件用于显示视频。
2.和console的程序一样,设置opencv库环境,加入opencv头文件,并定义所需要的变量。
3.关键的是这一步,定义CvvImage类型的变量m_CvvImage,这个类型的变量里有函数DrawToHDC能在MFC的控件中显示视频。
还有一个关键的一步是设置定时器timer,MFC中不用while循序来更新每帧视频,取而代之的是在定时器timer的响应函数中实现视频的更新,在本程序中每100毫秒进入一次定时器,定时器响应时间可以更改。
这里给出“打开摄像头”和定时器timer的响应函数。
01void COpencvUIDlgDlg::OnOpencamera() //打开摄像头按钮的响应函数
02{
03// TODO: Add your control notification handler code here
04m_Video=cvCreateCameraCapture-1//打开摄像头
05
06if!m_Video
07return
08
09SetTimer1,100,NULL//设置定时器
10}
11
12void COpencvUIDlgDlg::OnTimer UINT nIDEvent//定时器的响应函数
13{
14// TODO: Add your message handler code here and/or call default 15// KillTimer(nIDEvent);
16m_Frame=cvQueryFrame m_Video//m_Frame是IplImage指针类型17m_CvvImage.CopyOf m_Frame,1//m_CvvImage是CvvImage类型
18m_CvvImage.DrawToHDC hDC,&rect
19//将CvvImage显示在picture控件中,hDC是picture控件的句柄.rect是picture的区域.
20b_flagProcess=1
21
22CDialog::OnTimer nIDEvent
23}
4.加入截图和保存视频功能。
本程序下载地址:/source/1617588
---------------------------------------------------------------------------------------------------------------------------------
可以对本程序进行二次开发,下面实现在上述程序的基础上实现Camshift跟踪算法。
Opencv中自带Camshift跟踪算法的实现(OpenCV\samples\c\camshiftdemo.c),不过是基于console的,在MFC中实现则不能用其本来的鼠标回调函数来定位目标,而要改用MFC的鼠标消息响应函数。
运行结果为:
本程序下载地址:/source/1617559。