计算机学习笔记5.docx
《计算机学习笔记5.docx》由会员分享,可在线阅读,更多相关《计算机学习笔记5.docx(27页珍藏版)》请在冰豆网上搜索。
计算机学习笔记5
内部文件
本周工作记录
2015.8.10——2015.8.14
<智慧云联信息技术(北京)有限公司>
版本
编制者
王琳珂
编制日期
2015-08-14
审核者
审核日期
批准者
批准日期
签字日期
2015年08月14日
目录
1.海康摄像头视频自动抓图3
1.1开启预览之后自动保存每帧图片为BMP格式4
1.2不预览情况下自动保存图片5
1.3编写代码查看保存一张图片所用时间7
2.WIN7系统下搭建LINUX虚拟机9
2.1工具9
2.2安装VMware9
2.3搭建LINUX虚拟机12
2.4安装后的基本设置17
3.批处理删除VS工程下的中间文件19
4.Ubuntu中利用gcc和gdb编译和调试程序23
4.1单个C源文件的编译(参数-o)23
4.2多个C源文件的编译(参数-c和-o)23
4.3利用gdb调试程序25
1.海康摄像头视频自动抓图
各个函数初始代码:
函数:
InitInstance(HINSTANCE,int)
BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)
{
//前面的原代码不变,后面加入如下摄像头初始化设置
//---------------------------------------
hDC=GetWindowDC(hWnd);
//初始化
NET_DVR_Init();
//设置连接时间与重连时间
NET_DVR_SetConnectTime(2000,1);
NET_DVR_SetReconnect(10000,true);
//注册设备
NET_DVR_DEVICEINFO_V30struDeviceInfo;
lUserID=NET_DVR_Login_V30("192.168.1.64",8000,"admin","zhylxxjs201412",&struDeviceInfo);
if(lUserID<0)
{
//在窗口上输出错误提示
TextOut(hDC,200,200,_T("Loginerror"),11);
//通过变量error查看错误信息
interror=NET_DVR_GetLastError();
returnFALSE;
}
returnTRUE;
}
开启预览函数:
RealPlay()
voidRealPlay()
{
//启动预览并设置回调数据流
NET_DVR_PREVIEWINFOstruPlayInfo={0};
struPlayInfo.hPlayWnd=hWnd;//需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
struPlayInfo.lChannel=1;//预览通道号
struPlayInfo.dwStreamType=0;//0-主码流,1-子码流,2-码流3,3-码流4,以此类推
struPlayInfo.dwLinkMode=0;//0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RSTP/HTTP
lRealPlayHandle=NET_DVR_RealPlay_V40(lUserID,&struPlayInfo,NULL,NULL);
if(lRealPlayHandle<0)
{
TextOut(hDC,200,200,_T("NET_DVR_RealPlay_V40error"),26);
inti=NET_DVR_GetLastError();
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
return;
}
}
关闭预览函数:
PlayEnd()
voidPlayEnd()
{
//关闭预览
NET_DVR_StopRealPlay(lRealPlayHandle);
//注销用户
NET_DVR_Logout(lUserID);
//释放SDK资源
NET_DVR_Cleanup();
}
1.1开启预览之后自动保存每帧图片为BMP格式
NET_DVR_CapturePicture功能:
预览时,单帧数据捕获并保存成图片。
BOOLNET_DVR_CapturePicture(
LONGlRealHandle,
char*sPicFileName
);
Parameters:
lRealHandle[in]NET_DVR_RealPlay或NET_DVR_RealPlay_V30的返回值
sPicFileName[in]保存图象的文件路径(包括文件名)。
路径长度和操作系统有关,sdk不做限制,windows默认路径长度小于等于256字节(包括文件名在内)。
ReturnValues:
TRUE表示成功,FALSE表示失败。
获取错误码调用NET_DVR_GetLastError
Remarks:
(1)在调用该接口之前可以调用NET_DVR_SetCapturePictureMode设置抓图模式,默认为BMP模式。
如果抓图模式为BMP模式,抓取的是BMP图片,保存路径后缀应为.bmp,例如:
sPicFileName="D:
\\test.bmp";如果抓图模式为JPEG模式,抓取的是JPEG图片,保存路径后缀应为.jpg,例如:
sPicFileName="D:
\\test.jpg"。
(2)调用NET_DVR_CapturePicture进行抓图,要求在调用NET_DVR_RealPlay_V40等接口时传入非空的播放句柄(播放库解码显示),否则时接口会返回失败,调用次序错误。
在D盘新建文件夹Picture,用来保存开启视频后抓取的每一帧图片。
其中的一个难点是,自动保存图片的时候每一张图片的名字是否可以自动创建。
例如,
test1.bmp,test2.bmp,test3.bmp......这里需要用到C++中的一些语法知识。
(1)int转string
(2)多个string之间的连接
(3)String转char*
此处需要注意strings;s.data()或者s.c_str()的类型是constchar*
RealPlay()函数中写入实现此功能的代码:
for(i=1;i!
=0;i++)
{
stringstreamstrStream;
strStream<
stringFileBMPName="D:
\\Picture\\test"+strStream.str();
FileBMPName+=".bmp";//后缀名.bmp
//预览时,单帧数据捕获并保存成图片
NET_DVR_CapturePicture(lRealPlayHandle,(char*)FileBMPName.data());
Sleep(40);//执行挂起40ms,即1s截取25张图片,需要带上头文件windows.h
}
编译通过之后运行程序,点击菜单开启预览,此时每隔40ms保存一帧图片,保存结果如下:
1.2不预览情况下自动保存图片
在文件菜单下添加“截图”,根据ID号将该菜单加到程序中以实现截图功能。
首先声明截图函数voidCapturePicture();
分析菜单选择中添加截图的ID号:
caseID_32773:
CapturePicture();
break;
NET_DVR_CaptureJPEGPicture功能:
单帧数据捕获并保存成JPEG图。
BOOLNET_DVR_CaptureJPEGPicture(
LONGlUserID,
LONGlChannel,
LPNET_DVR_JPEGPARAlpJpegPara,
char*sPicFileName
);
Parameters:
lUserID[in]NET_DVR_Login或NET_DVR_Login_V30的返回值
lChannel[in]通道号
lpJpegPara[in]JPEG图像参数
sPicFileName[in]保存JPEG图的文件路径(包括文件名)
ReturnValues:
TRUE表示成功,FALSE表示失败。
获取错误码调用NET_DVR_GetLastError
截图函数:
CapturePicture()
voidCapturePicture()
{
for(i=1;i!
=0;i++)
{
stringstreamstrStream;
strStream<
stringFileJPEGName="D:
\\Picture\\test"+strStream.str();
FileJPEGName+=".jpg";
NET_DVR_JPEGPARAstruJpegpara={0};
struJpegpara.wPicQuality=2;//图片质量系数:
0-最好,1-较好,2-一般
struJpegpara.wPicSize=0;
NET_DVR_CaptureJPEGPicture(lUserID,1,&struJpegpara,(char*)FileJPEGName.data());//单帧数据捕获并保存成JPEG图
}
}
从运行结果看出每秒钟只能抓取几张图片。
1.3编写代码查看保存一张图片所用时间
因为在不预览情况下保存图片的效率很低,为了查看每帧图片的保存时间,我们添加相应的开始时间和结束时间函数,来计算程序运行时间。
#include
#include//关键
usingnamespacestd;
intmain()
{
clock_tstart,finish;
doubletotalTime;
start=clock();
//需要测试运行时间的代码段放在这
finish=clock();
totalTime=(double)(finish-start);
cout<<"花费"<return0;
}
截图函数:
CapturePicture()
voidCapturePicture()
{
clock_tstart,finish;
doubletotalTime;
for(i=1;i!
=0;i++)
{
start=clock();//本行设置断点
stringstreamstrStream;
strStream<
stringFileJPEGName="D:
\\Picture\\test"+strStream.str();
FileJPEGName+=".jpg";
NET_DVR_JPEGPARAstruJpegpara={0};
struJpegpara.wPicQuality=2;//图片质量系数:
0-最好,1-较好,2-一般
struJpegpara.wPicSize=0;
NET_DVR_CaptureJPEGPicture(lUserID,1,&struJpegpara,(char*)FileJPEGName.data());//单帧数据捕获并保存成JPEG图
//Sleep(40);
finish=clock();
totalTime=(double)(finish-start);//本行设置断点
}
}
程序中在截取一张图片的开始和结束处分别设置了断点,利用F5快捷键调试查看截取一张图片的时间。
totalTime的值为216ms,也就是说截一张图需要216ms,那么1s只能截图4~5张,可见该方法的抓图效率太低。
2.WIN7系统下搭建LINUX虚拟机
如果日常工作使用LINUX和WIN7双操作系统,每次更换系统总要关机重启很不方便,所以在WIN7下搭建LINUX虚拟机使用。
2.1工具
以下是必备的文件:
(1)ubuntu镜像文件,32位的.iso文件,下载地址:
(2)VMware安装文件,XX直接搜索即可下载。
操作步骤:
(1)首先安装VMware,在WIN7上搭建一个虚拟环境。
(2)在VMware的基础上,通过ISO镜像文件,搭建LINUX虚拟机。
2.2安装VMware
双击VMware的安装包,出现如下界面,点击下一步,
继续下一步,“我接受许可协议中的条款”,下一步,“典型”,出现如下界面,这里,要选择安装路径。
请记住,不要有中文和空格!
当然,并非说有空格和中文会出什么问题,但是最好不要有。
比如JAVA环境的搭建,就不能有,因为是国外的软件,人家不认识中文。
为了以后出现莫名其妙的意外,最好不要加。
下一步,“取消启动时检查产品更新”,下一步“取消帮助改善VMwareWorkstation”,下一步,下一步,继续,开始安装
安装过程中需要输入许可证密钥,XX搜索到VMwareWorkstation11序列号:
1F04Z-6D111-7Z029-AV0Q4-3AEH8
输入,安装向导完成。
2.3搭建LINUX虚拟机
双击VMwareWorkstation软件,打开界面,如图:
开始创建虚拟机。
可以直接点击主界面:
创建新的虚拟机
也可以:
文件-->新建虚拟机
到了这一步,如下图,仍然选择“典型”安装。
然后,点击下一步
因为我们是通过镜像文件安装,所以选择“安装程序光盘映象文件(ISO)(M)”这个选项,浏览选择镜像文件所在的位置。
如果是通过光盘安装,就选择上面那个。
点击下一步
用户名和密码别忘记了,这是一个普通用户,安装完毕后,你会靠它登录系统的。
这里的密码是:
ubuntu,点击下一步
安装位置,最好不要有中文和空格。
还有,安装的盘要有足够大的空间。
点击下一步
磁盘大小,看个人需求,20G够用,此处不再修改。
点击下一步,完成。
之后会出现如下消息框:
点击取消更新
正在安装中。
截图如下,不需要任何操作,不过安装是个挺漫长的过程。
安装成功,如图所示,为我的登录界面。
输入之前设定密码ubuntu,就可以登录了。
2.4安装后的基本设置
(1)登陆之后,先设置时间和日期
(2)点击菜单虚拟机下的安装VMwareTools,按照提示操作进行安装。
(3)搜索终端terminal,出现命令窗口。
点击打开终端
在左侧一列图标中右击终端,点“锁定到启动器”,方便以后使用。
(4)修改系统语言为中文。
SystemSetting——LanguageSupport
点击添加或删除语言,添加Chinese(simple),添加完成后,在菜单和窗口的语言中将汉语(中国)拉到最上面,同时将“地区格式”一栏中的显示数字,日期和货币数额的格式也设置为汉语(中国)。
设置完成后,在终端执行重启命令reboot即可让以上更改生效。
3.批处理删除VS工程下的中间文件
VS2012打开一个工程,转换成功之后,在工程目录中可以看到多了一个sdf文件和一个ipch文件夹(该文件夹子目录下有一个ipch文件),起码有几十兆,这些文件删除之后并不会对工程本身有任何影响。
所以我们建立一个批处理(bat)文件,用来删除VS工程中的中间文件。
步骤:
(1)新建一个文本文档;
(2)在txt文档中输入相关批处理语句,下面会详细说明两种批处理方法;
(3)保存写好的文档,将扩展名.txt修改为.bat,此时系统会提示你修改扩展名会导致文件不能用,这时直接点击确定。
(4)修改完扩展名后,文件的图标会变成类似两个齿轮一样,这时把该文件放在工程目录下,双击该文件,就可以执行批处理删除。
弹出的窗口会提示你按任意键执行,删除成功之后按任意键退出就可以了。
下面是两种批处理方法。
方法一:
clearVS.bat
@ECHOOFF//批处理的开始语句
del/S*.sdf//del是删除文件命令
rd/Sipch//rd是删除文件夹命令
或者:
del/S*.ipch//因为文件夹并不占用硬盘空间,只需把子目录下的ipch文件删除
执行前:
双击clearVS.bat,
输入Y,sdf文件和ipch文件夹已删除。
del命令一共有5个参数,分别是/p、/f、/s、/q和/a。
/p参数的作用是删除每一个文件之前提示确认,这个参数的主要作用是当你要删除多个文件时(不用通配符)提示你确认删除,如果你只是删除单个文件或多个文件(用通配符),默认是不会提示你确认删除的。
/f参数的作用是强制删除只读文件,当我们删除只读文件时,系统会提示拒绝访问,这时就要利用这个参数了。
/s参数的作用是从所有子目录删除指定文件。
/q参数的作用是删除全局通配符时,不要求确认。
当我们利用全局通配符来删除多个文件时,默认会提示你是否删除所有文件,如果你用了这个参数,系统就不会提示你了。
/a参数的作用是根据属性选择要删除的文件。
其中,r表示只读文件,s表示系统文件,h表示隐藏文件,a表示存档文件,还有一个-表示“否”的前缀。
下面举个实例来说明:
我要删除D:
\test目录下的所有只读文件,此时我只需在命令行中输入del/a:
rD:
\test\*就可以了,相反,如果我要删除除了只读以外的所有文件,我就要输入del/a:
-rD:
\test\*。
rd命令只有2个参数,分别是/s和/q。
/s参数的作用是除目录本身外,还将删除指定目录下的所有子目录和文件。
用于删除目录树。
如果不带这个参数就只能删除空文件夹。
/q参数的作用是安静模式,带/s删除目录树时不需要确认。
方法二:
clearVSTemp.bat
RemDeleteVStemporaryfile//Rem是指定由DOS忽略的命令行
Rem****************************
@echoDeleteVStemporaryfile
@dir/w/s*.sdf*.ipch//删除sdf文件和ipch文件
@echo以上为当前目录及子目录临时文件,请按任意键确认删除!
!
!
@pause
@for/r.%%ain(.)do@ifexist"%%a\*.sdf"del"%%a\*.sdf"
@for/r.%%ain(.)do@ifexist"%%a\*.ipch"del"%%a\*.ipch"
@echo删除成功!
@pause
Rem****************************
双击clearVSTemp.bat,
按任意键继续,删除成功之后按任意键退出。
注意:
本方法删除的是sdf文件和ipch文件夹下的ipch文件,ipch文件夹没必要删除。
4.Ubuntu中利用gcc和gdb编译和调试程序
4.1单个C源文件的编译(参数-o)
将一个C源文件编译成可执行文件的方法,标准格式如下:
gcc-o目标文件源文件
如gcc-ohellohello.c
命令执行之后会产生一个hello文件,执行hello文件即输出:
”HelloWorld”
gcc最基本最常用的参数有:
-c,只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
-ooutput_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。
如果不给出这个选项,gcc就给出预设的可执行文件a.out。
-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。
4.2多个C源文件的编译(参数-c和-o)
对于一个文件,我们可以直接编译成可执行文件。
而实际的开发过程中,可能由很多人同时开发,每个人只开发部分的C源程序,最后再连接成一个可执行程序。
main.c程序如下:
//filename:
main.c
#include
intmain()
{
intm;
printf("Enteraninteger\n");
scanf("%d",&m);
printf("absolutevalueis%d\n",absf(m));
return0;
}
sub.c程序如下:
//filename:
sub.c
#include
intabsf(inta)
{
if(a<0)
{return-a;}
else
{returna;}
}
main.c编写完之后进行编译,以确认程序的语法是否正确。
如果执行前面提到过的语句gcc-omainmain.c会提示未定义的参照absf。
这是文件sub.c中的函数。
所以,main.c在编译时要用另外的参数-c来编译,执行gcc-cmain.c,生成main.o文件。
main.o这个文件是不可执行的,-c参数代表只编译,但在编译过程中能够检查出是否存在语法错误。
用同样的方式编译sub.c,执行gcc-csub.c,生成sub.o文件。
最后再用-o参数来连接到一起:
执行gcc-omainmain.osub.o生成最终的main文件就可以运行了。
4.3利用gdb调试程序
上面的例子程序都可以编译通过,并且能够执行。
实际的开发过程中就不一定这么幸运了,经常会遇到程序虽然可以通过编译,但一运行就出错的情况。
这就要用到Ubuntu下的调试工具gdb了。
gdb是linux下广为应用的程序调试工具,一般来说,gdb主要帮助你完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。
(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
启动gdb后,你就被带入gdb的调试环境中,就可以使用gdb的命令开始调试程序了,gdb的命令可以使用help命令来查看,如下所示:
1、用gdb调试之前,要将调试信息编译到目标程序中,需要用到相关的参数-g,按照下面的步骤重新编译上面的两个C源文件。
执行gcc-c-gmain.c和gcc-c-gsub.c,然后连接这两个程序,gcc-omai