一、视频开发之 DirectShow、 OpenCv、 Vfw
VFW
微软最早推出的关于数字视频的一个软件开发包,VFW的核心是AVI文件标准。现在还有使用,但更多时候被directshow、OPENCV等开发库替代。
Vfw直接操作驱动,偏底层一些,比较灵活,但是只是提供了视频IO的途径。
OpenCv(开源)很庞大,内部封装了vfw,同时提供了很多视频算法和功能,比如剪辑录制等,支持多种视频格式,功能很强大。但从上手到熟悉会慢一些。
DirectShow(微软)是基于com的组件方式,提供了多种常见视频音频格式的filter,根据微软的示例代码可以很快速的搭建一个视频音频项目,也可以自己构建filter来满足实际的需求,使用起来很方便,扩展起来也比较容易。但是发布的时候需要带着DirectX库。
功能上:opencv>directshow>vfw
开发效率上:directshow>vfw>opencv
开发难度上:opencv>vfw>directshow
利用Vfw开发包进行数字视频开发时Vc编程环境的设置,如下图:
二、解决摄像头拖影(转)
故障现象:近日学校装了宽带,我就购买了一个摄像头,在电脑市场测试的时候画面流畅清晰,没有丝毫拖影。
晚上回到宿舍,兴高采烈地装好驱动,打开摄像头后发现画面的清晰度还可以,但是有明显的拖影(本地播放),心想在商家测试的时候没有问题为什么回来就产生拖影了呢?
分析解决:我将摄像头拿回销售商处,结果画面仍然流畅,没有丝毫拖影,说明摄像头本身没有问题。本人的电脑配置是AMD 雷鸟1.2GHz,精英K735S主板,翔升MX440的显卡,256MB DDR内存。应该说电脑性能不是造成拖影的原因。于是本着先软后硬的原则,我先下载了最新的摄像头驱动和相应的主板驱动,可问题依旧。
直到有一天晚上在宿舍,闲来无事,我移动摄像头浏览宿舍全景时发现有的时候摄像头拍摄的内容会很流畅,有的时候有明显拖影。仔细观察才发现,当摄像头对到光线明亮的地方摄出的画面就很流畅,其他情况就有拖影。想到曝光时间和图像速度成反比这个道理,我一下就知道了原因。原来在商家测试的时候都是白天,画面自然流畅。而我们学生一般都是晚上回宿舍才用摄像头,再加上宿舍光线不够明亮,因此摄像头为了保证画面的质量自然延长曝光时间也就造成了拖影的现象。
找到原因就好解决了。我按照“开始→所有程序→SOVIC PC CAMERA→AMCAP” 的顺序打开摄像头的驱动控制程序,在里面的“OPTIONS→Video Capture→Filter”里有很多调节的选项,在最下面的曝光时间上默认是自动调节(见图1)。把AUTO后面的钩去掉,把曝光时间调节到合适的速度(如图2),如果嫌画面偏暗,可以通过提高显示亮度和打开背光补偿来提高亮度。久违的流畅画面终于出现在我的电脑上了。至此,关于摄像头拖影的问题全部解决。
原理是这样的,按照我看的网站给的说法,摄像头的曝光时间和图像速度成反比,那么曝光时间越短,图像速度就越快。这样就可以通过摄像头的软件进行调整。以我的摄像头(天敏公司的天弓摄像头有驱版)为例,先安装摄像头自带的软件10Moons USB PC Camera 2.3 ,打开软件,然后点设置按钮,弹出对话框点“设备设置”,再点“视频捕捉属性”,在弹出对话框里点“相机”,你会看到“曝光”一项,去掉“自动”,然后“ 确定”。设置完后你会发现,拖影现象真的改善了好多,你可以试一下,再将”曝光“的数值设为0、50、100,你会发现设为0时,图像相当的灰暗,近乎看不清,但图像一点拖影、停顿感都没有。曝光值越高,拖影、停顿感越明显,你可以自行设置曝光的数值,并根据光线情况,达到理想的效果。
你可以根据示例,对照自己的摄像头,在自带软件或驱动里设置一下,相信拖影现象能得到改善。再说一点,很多朋友买了摄像头,也不懂怎么调试,就随便说某款摄像头不好,其实就是大家不知道怎么调试。
利用Vfw开发包进行数字视频开发时Vc编程环境的设置
三、 关于vc编程
自我感觉现在用vc编程的习惯还是停留在vb那种面向过程的编程套路。也就是在面向对象的开发平台上(vc)运用面向过程的编程思路。平时要注意培养在vc的平台下运用面向对象的编程思路。(详看vc技术内幕第15章那两个关于student的例子。)这个例子就是显示学生的姓名和年纪,如果没有看过vc技术内幕这本书,我自己实现的话肯定是直接在主框架内定义全局函数name和grade,然后接收用户输入并显示出来。请参看vc技术内幕实现的方法,以领悟面向对象编程的精髓。
四、关于捕获两路摄像头
我的电脑连着两个usb口摄像头,目前可以做到通过命令WM_CAP_DLG_VIDEOSOURCE调出如图这个视频源对话框然后用户通过选择不同的设备可切换这两个摄像头。我感觉这样很不方便用户操作,不知道vb中有没有其他代码等方式来替代这个对话框选择的方式呢?一直找不到可以实现的方法,望朋友们给予指点,谢谢!或者跳出这个思路,有没有其他的方法可以实现捕获两路摄像头呢?
如果你的系统里装有多个捕获设备, 你可以在发送WM_CAP_DRIVER_CONNECT消息时用wParam参数指定使用哪一个, 此参数是登记在SYSTEM.INI文件的[drivers]一节里的列表中的某一项, 0为第一个.
不知道上面这段话中的多个捕获设备指什么呢?我的电脑连有两个u口摄像头,用上述命令只有0时能捕获一个,输入其他数字完全捕获不到。只有通过Video Source调出视频源对话框才能选择不同设备。想请教下大家的意见除了调出对话框这个方法有没有其他方法可以捕获两路u口摄像?
五、关于小波变换
你知道傅立叶变换吧,傅立叶变换是把函数乘以e的-jwt再积分,小波变换是用函数本身再乘以一个函数再积分,被乘的这个函数像小波一样叫小波函数。
对于图像经过小波变换后就把图像分成了高频部分和低频部分,高频反应变化尖锐的部分,低频反应大体效果,要是去噪的话就把高频部分再分成高频部分和低频部分,像2叉树那样分下去,分几级自己限制,最后把最底层的合在一起(这样中间产生的高频部分就被去掉了),从而实现去噪。
就会这些了,建议到百度文库下篇文章看看,有的解释的很好。
小波变换和去噪
通俗的讲就是剥大蒜的过程,也就是不断的分层,使得信号拆分成各种频段(根据采用频率而定),而这一过程要用到低通滤波器和高通滤波器,而小波去噪就是在高频部分(因为通常白噪声出现在高频部分)改变数字量,运用一些算法去除一些混有噪声的数字,然后再运用重构低通滤波器和高通滤波器把刚刚分层的频段加起来,差不多就是拼凑大蒜的过程吧。
http://bbs.matwav.com/viewthread.php?tid=274105&extra=&page=1
【求助】各位达人:能不能用最通俗的表达解释一下小波变换的基本概念?
小波的“小“是相对于傅氏变换中的sin(x)而言的,sin(x)的波形很长(无止境),但是小波的波形很短,很快就衰减为0。但他们的作用一样,都是把信号从时间域变换到频率域。由于sin(x)很长很大,就把新出来的这个波叫做小波了。
小波变换就是用特殊的基函数(小波)来展开和研究任意一个函数。
fourier就是用三角函数基
wavelet就是用小波基
小波变换实质上就求信号在各个小波函数上的投影值。
你就把小波函数组认为是一个向量空间的基就行了。
然后把函数信号在这个基上展开,本质与傅立叶变换一样的
http://apps.hi.baidu.com/share/detail/33117471
基的概念
我们要明确的是基的概念。两者都是基,信号都可以分成无穷多个他们的和(叠加)。而展开系数就是基与信号之间的内积,更通俗的说是投影。展开系数大的,说明信号和基,是足够相似的。这也就是相似性检测的思想。但我们必须明确的是,傅里叶是0-2pi标准正交基,而小波是-inf到inf之间的基。因此,小波在实轴上是紧的。而傅里叶的基(正弦或余弦),与此相反。而小波能不能成为Reisz基,或标准稳定的正交基,还有其它的限制条件。此外,两者相似的还有就是PARSEVAL定理。(时频能量守恒)。
六、关于mts格式
许多高清DV玩家拍摄的视频格式并非常见的avi, mp4, mpg, mov, asf等高清视频格式,而是特殊的mts格式。mts格式无法在其他设备中进行播放,不能与别人很容易地分享,也不方便收藏保存,所以一般情况下都要将mts格式的高清视频转换为avi, mp4, mpg, mov, asf等高清视频格式,这就需要使用专业的mts格式转换器软件来帮忙了。"私房MTS视频格式转换器软件"专门为mts电影/视频格式转换而设计,功能专业且简单易用,支持将mts格式的高清视频转换为各种常用视频格式,包括avi, mp4, mpg, mov, asf, wmv, vob, mkv...重要的是,不会损失mts高清电影视频的画质,保证了输出视频的质量依然高清。无论是将mts格式转换avi,还是将mts格式转换mp4,mpg,mov等格式操作都完全相同,以下就以mts格式转换avi视频为例,详细讲解如果使用这款mts格式转换器软件。
七、基本 C++ 数据类型(内置类型)
类型是对系统中的实体的一种抽象,它描述了某种实体的基础特性,包括值的表示、存储空间的大小以及对该值的操作。C++的数据类型包括基本数据类型和构造数据类型两类。构造数据类型又称复合数据类型,它是一种更高级的抽象。当变量被定义为某种类型时会受到系统对该类型的特别保护,确保其值不受非法操作。
C++语言的基本数据类型有如下四种:
·整型,说明符为int;
·字符型,说明符为char;
·浮点型(又称实型),说明符为float(单精度),double(双精度);
·空值型,说明符为void,用于函数和指针。
为了满足各种情况的需要,除了void型外,上述的三种类型前面还可以加上修饰符改变原来的含义。
signed 表示有符号
unsigned 表示无符号
long 表示长型
short 表示短型
上述4种修饰符都适用于整型和字符型,只有long 还适用于双精度浮点型。
八、C++标准库提供的数据类型
list、map、vector(顺序容器和关联容器类型)
在C++中,像string、complex、vector、list这样的标准库类型都被设计成类。
Vector容器类型,它为内置数组提供了一种基于对象的替代品。
八、基于模板的类Collections:Template-Based Classes
MFC predefines two categories of template-based collections:
CArray, CList, CMap
CTypedPtrArray, CTypedPtrList, CTypedPtrMap
CArray<int, int> myArray; CArray<CPerson, CPerson&> myArray; CPerson person; myArray->Add( person ); CTypedPtrArray<CObArray, CPerson*> myArray;
MFC的数组类支持的数组类似于C++中的常规数组,可以存放任何数据类型。C++的常规数组在使用前必须将其定义成能够容纳所有可能需要的元素,而MFC数组类创建的对象可以根据需要动态地增大或减小,数组的起始下标是0,而上限可以是固定的,也可以随着元素的增加而增加,数组在内存中的地址仍然是连续分配的。
MFC定义了数组模板类CArray,并针对各种常用变量类型定义了CByteArray,CWordArray,CUIntArray,CDWordArray,CStringArray,CObArray,CPtrArray。
类对象数组定义
1、对象数组就是指数组元素为对象的数组。数组中的所有元素具有相同的已声明数据类型。
2、定义和使用对象类型数组与普通数组一样。对象类型数组的元素可以通过其索引进行检索,并且可以像处理给定类型的普通对象一样进行处理。
定义一个对象数组,例如:Student[] students = new Student[5];//声明一个students对象数组,该数组有5个元素,每个元素都是类Student的对象。
九、堆栈
栈是进程启动时系统分配给进程的地址空间,栈结构即FILO,进程终止时栈自动释放由系统回收,因此没有泄露的隐患。栈的数据是易失的,超出了作用域数据就会丢失。
堆我理解是全局内存,进程需要申请才会分配,没有作用范围因此存在堆上的数据不是易失的
new和delete操作符申请到的内存是HEAP上的,所以进程终止前必须释放否则会造成内存泄露(leap)。
myclass MyObject; //这样定义,对象存放在栈中,当退出对象作用域时,由编译器负责释放。 myclass MyObeject = new myclass; //向系统申请一块内存,在堆中,使用完毕,由程序员负责释放
你能够控制的内存空间叫堆,可以用new delete malloc free等函数来进行分配等工作。
而栈是由系统负责的,你没有权利操作栈——虽然你的程序中的大部份数据都是存在栈中,但具体放在哪儿、怎么放,与你无关。之所以要这么严格,是因为栈的FIFO的机制要求看起来简单,但真正用起来很烦人,稍有不慎,比如说用了两个push,而只用了一个pop,则以后所有对栈的操作都错了,后果不堪设想。
而相比之下,管理堆就没有那有费心了,就算new 过以后没有delete,也只是一个内存漏洞而已,浪费了一点空间,没有什么严重后果。正因为这样,系统才会把管理堆的权利下放(当然了,还没有完全下放)。
十、在一个类(A)中使用另一个类(B)的成员变量
有3种方法:
1:定义一个类2的实例对象;
2:把类2的成员变量声明为静态变量(static);
m_suijishu=CTyuDlg::Chuzhi;
3:或是声明成友元
十一、_T('"')
十二、静态成员数组的初始化
十三、定义动态数组
MFC用CArray,对应的几种Array如CStringArray
STL用vector,list等
此外,申请动态内存:
C用malloc()或calloc()
C++用new
使用::std::vector<>作为管理动态数组的优先选择(CArray<> VS ::std::vector<> )
网址:http://www.vckbase.com/document/viewdoc/?id=844
十四、MFC和STL的new冲突
十五、vector声明必须using namespace std
#include<vector>
#include<string>
using namespace std; //将这句去掉的话,程序编译通不过,请问大家是什么原因?
原因:根据C++标准,vector是在一个名为std的名字空间中,所以要加这一句
using std::vector 与 using namespace std;
using namespace std,std里的都可以使用,using std::只使用指定的类型,std其他的类型就不行。
建议用using namespace std;
十六、不能用全局变量保存DC问题
再来解释一下前面说的为什么不能用全局变量保存DC问题:其实DC也是用句柄来标识的,所以也具有句柄的不确定性,就是只能随用随取,不同时间两次取得的是不同的(使用过文件句柄地话,应该很容易理解的)。那么我们用全局变量保存的DC就没什么意义了,下次使用只是什么也画不出来。(这一点的理解可以这样:DC需要占用一定的内存,那么在频繁的页面调度中,位置难免改变,于是用来标志指针的句柄也就不同了)。
十七、delete m_pdc与 m_pdc->DeleteDC()的区别
十八、构造函数中调用 GetDlgItem 出现debug assertion failed错误
CAnalysisView::CAnalysisView() : CFormView(CAnalysisView::IDD) { //{{AFX_DATA_INIT(CAnalysisView) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // TODO: add construction code here ••• pWnd= GetDlgItem(IDC_PICTURE1); //返回指定对话框中的控件句柄 ••••• }
一语惊醒梦中人啊!!!
常见问题:DoModal后调用GetDlgItem导致以上错误
产生原因:这时候窗口已经关闭,没有DlgItem一说
解决方法:在退出前保存为成员变量,Member Vari
十九、指针问题~0xcdcdcdcd是不是空?
http://topic.csdn.net/t/20031009/14/2336943.html
二十、视频格式与视频编码的区别
二十一、%02d和%2d 什么区别
假如 a = 2;
printf("%02d",a) ->输出 02
printf("%2d",a) ->输出 2
也就是说你那里的2是占位符,如果不到两位就用0补
二十二、TCHAR和char的区别?
tchar 在unicode下是wchar(双字符)
而普通是char
char在两者都是char
因为C++支持两种字符串,即常规的ANSI编码(使用""包裹)和Unicode编码(使用L""包裹),这样对应的就有了两套字符串字符串处理函数,比如:strlen和wstrlen,分别用于处理两种字符串 微软将这两套字符集及其操作进行了统一,通过条件编译(通过_UNICODE和UNICODE宏)控制实际使用的字符集,这样就有了_T("")这样的字符串,对应的就有了_tcslen这样的函数 为了存储这样的通用字符,就有了TCHAR: 当没有定义_UNICODE宏时,TCHAR = char,_tcslen = strlen 当定义了_UNICODE宏时,TCHAR = wchar_t , _tcslen = wstrlen 当我们定义了UNICODE宏,就相当于告诉了编译器:我准备采用UNICODE版本。这个时候,TCHAR就会摇身一变,变成了wchar_t。而未定义UNICODE宏时,TCHAR摇身一变,变成了unsigned char 。这样就可以很好的切换宽窄字符集。 tchar可用于双字节字符串,使程序可以用于中日韩等国 语言文字处理、显示。使编程方法简化。
TCHAR 是为了统一多语言编码而设计的。
ANSI 单字符编码
UNICODE 双字节字符编码
UTF-8 三字节字符编码
通过不同的编译选项,生成不同的支持不同编码的程序。
默认情况下的,ASCII,两者是互通的。
在其它方面,就不一致了。