20120505保存摄像数据实践(失败的实践)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
保存摄像数据实践
一、创建一个保存摄像数据的MFC对话框程序SaveCamData:
二、应用程序界面
三、添加依赖项
将cxcore200.lib cv200.lib highgui200.lib添加到解决方案属性中的项目依赖项中将头文件"cv.h"、"highgui.h"包含进头文件SaveCamData.h中
#include"cv.h"
#include"highgui.h"
四、为对话框类CSaveCamDataDlg添加三个变量:
// 摄像头变量
CvCapture* capture;
// 摄像帧图像变量
IplImage* frame;
// 视频写入器变量
CvVideoWriter* writer;
// 保存标志
bool saveflag;
在对话框类的构造函数中,默认将这三个变量初始化为NULL:
CSaveCamDataDlg::CSaveCamDataDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSaveCamDataDlg::IDD, pParent)
, capture(NULL)
, frame(NULL)
, writer(NULL)
, saveflag(false)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
将NULL都修改为0
五、为按钮添加各个事件代码:
1、开启摄像头
void CSaveCamDataDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
capture = cvCaptureFromCAM( 0 );
}
2、保存摄像
void CSaveCamDataDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
saveflag=true;//保存的标志,为true,表示可以保存
int isColol=1;
int frameW=640;
int frameH=480;
int fps=125; //捕捉帧率
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),fps,cvSize(frameW,frameH),isColol);
while(saveflag)
{
frame = cvQueryFrame( capture );
cvWriteFrame(writer,frame );
//char c = cvWaitKey(10);
//if( c == 27 ) break;
}
}
3、停止保存摄像
void CSaveCamDataDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
saveflag=false;//保存标志为false,停止保存
}
4、关闭视频
void CSaveCamDataDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
cvReleaseVideoWriter(&writer);
cvReleaseImage(&frame);
cvReleaseCapture( &capture );
}
六、调试出现故障:
调试的时候,出现了问题,就是按下“保存摄像”按钮后,响应的事件就是开始保存摄像,但是窗口的焦点并没有释放,以至于窗体停滞不响应,“停止保存摄像”按钮无法按下,程序也无法关闭,只能强行中止调试。强行中止调试后,检测保存的摄像,发现视频文件可以播放,但是不能拖动,因为没有正常将writer销毁给视频一个有效的终结。
七、故障排检方案一:
在开始保存摄像按钮事件中代码改为:
void CSaveCamDataDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
saveflag=true;//保存的标志,为true,表示可以保存
int isColol=1;
int frameW=640;
int frameH=480;
int fps=125; //捕捉帧率
int moretime=0;
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),fps,cvSize(frameW,frameH),isColol);
while(saveflag&&(moretime<100))
{
frame = cvQueryFrame( capture );
cvWriteFrame(writer,frame );
//char c = cvWaitKey(10);
//if( c == 27 ) break;
moretime++;
}
}
即添加一个整型参数进行计数,计数100经过时间为6秒,表示6秒后循环中止。程序主界面在这个时间内卡住,处理完后,焦点释放,程序主界面恢复正常,按下停止保存摄像按钮,再按下关闭视频按钮时,出现报错窗体:
检查视频文件,则看到视频文件的持续时长为1秒。这表示视频有正常中止,可是为什么会出现这种报错现象,而且将出错信息定位到文件xstring中的_Traits_helper::copy_s<_Traits>(_Myptr(), _Myres, _Right._Myptr() + _Roff, _Num);位置呢?难道是因为没有为这些要注销掉的变量分配静态空间?还有为什么会出现在进行摄像数据保存的时候,程序会直接卡住无法释放焦点?
八、用线程来解决程序卡住的问题:
在窗体类的头文件SaveCamDataDlg.h中,添加结构体和线程函数体,注意,在窗体类标志之外:
struct threadInfo
{
bool savewriter;//线程录像是否进行的标志
CString videoname;//摄像转录像的名称
};
//线程函数的声明:
UINT ThreadFunc(LPVOID lpParam);
为窗体类添加两个变量:
// 保存摄像标志
bool m_savewriter;