已有57人关注
程序开发范例宝典 实例426 摄像头监控录像 怎么设置成有动的时候录像,不动时不录呀
发表在C#图书答疑 2010-07-23
是否精华
版块置顶:
程序开发范例宝典 实例426 摄像头监控录像 怎么设置成有动的时候录像,不动时不录呀,想作个程序放在机房的电脑上,有人进去时就录像,保存成aiv文件,没有人进时就不录。一直录的话,很难去查记录,又占硬盘空间。


426
摄像头监控录像
实例说明
本例是为通过摄像头来实现监控录像的程序。运行本例后,单击【开始监控】
按钮,程序将自动开始录像,录像文件(lx.avi)将保存在D 盘根目录下。运行
程序,效果如图13.10 所示。
技术要点
在实例“简易视频程序”的技术要点中,使用的技术和相关函数已经介绍过。
在这里主要介绍如何将捕获的视频制作成 .AVI 媒体文件。实现技术为主要通过
SendMessage 函数发送Windows 消息机制,消息值WM_CAP_FILE_SET_CAPTURE_F
ILEA 和WM_CAP_SEQUENCE,分别用来设置视频捕捉的文件名称和初始化视频流,
捕捉视频信息到文件:
private const int WM_USER = 0x400;
private const int WM_CAP_START = WM_USER;
private const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
private const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 2
0;
实现关键代码如下:
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC,WM_CAP_FILE_SET_CAPTURE_FILEA,0, hBmp.ToInt32
());
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
实现过程
(1)新建一个项目,命名为Ex13_09,默认窗体为Form1,添加一个类文件
(.CS),用于编写视频类。
(2)在Form1 窗体中,主要添加一个PictrueBox 控件,用于显示视频;添
加4 个Button 控件,用于开始监控、停止监控和监控程序。
(3)视频类中主要程序代码如下:
/// <summary>
///
开始录像
/// </summary>
/// <param name="path">
要保存录像的路径
</param>
public void StarKinescope(string path)
{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC,WM_CAP_FILE_SET_CAPTURE_FILEA,0, hBmp.ToInt32
());
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
}
/// <summary>
///
停止录像
/// </summary>
public void StopKinescope()
{
分享到:
精彩评论 3
小科_mrkj
学分:43 LV2
2010-07-23
沙发
读者朋友:
    您好,你说的功能得用物体自动识别技术,这个例子只能设置定时录像,不能检测识别是否有物体。
wufayou
学分:0 LV1
TA的每日心情
第五天
2023-03-18 21:24:17
2010-07-24
板凳
假设有一个原始的24bppRGB称为当前帧(图
像),一个灰阶的拷贝(当前帧)和一个具有灰阶的
前一视频帧(背景帧)。首先需要找出这两个帧发生
变化的区域在哪里。为此可以使用C撑的Diference
和Threshold滤波器:
,/生成滤波器
DiferencediffFilter=newDiference();
IFilter threFilter=new Threshold(15,255);
,/为不同的滤波器设定背景帧作为覆盖层
diffFilter.Overlaylmage=backgroundFrame;
,/使用滤波器
Bitmap tmpl=diffFilter.Apply(currentFrame);
Bitmap tmp2=threFilter.Apply(tmp1);
在这一步,按照特定的域值,在当前帧与前一帧
两帧中有所不同的地方获得一个白像素的图像。通过
计算像素数,如果像素总和大于一个预定的警告水
平,就可以认为是有运动发生。但因为光线照射,反
光等情况使得大部分摄像机产生噪音图像,在没有运
动的地方可以获得运动的噪音。为了去除随机的噪音
像素,可以使用Erosion滤波器,从而只获得确实有
运动的区域。
IFiltererosFilter=newErosion();
维普资讯 http://www.cqvip.com
Bitmap tmp3=erosFilter.Apply(tmp2);
至此,一般的检测器就做好了,如果需要的话还
可以把运动区域用高亮的颜色显示出来:
,/从原始图像中抽出红色通道
IFilter extrChannel=new ExtractChannel(RGB.R);
Bitmap redChannel=extrChanne1.Apply(image);
,,红色通道和运动区域合并
Merge mergeFilter=new Merge();
mergeFilter.Ovedaylmage=tmp3;
Bitmaptmp4=mergeFilter.Apply(redChanne1);
脏原始图像中替换红色通道
ReplaceOmnnelreplChannel=newRep~ I(RGB.R);
replChanne1.Channellmage=trap4;
Bitmaptmp5=replChanne1.Apply(image);
然而,如果运动对象是很轻微的移动,那么该法
将仅仅获得帧与帧之间的局部微小改变,不能获得整
个移动对象,故该方法还不是很理想。
其它方法的考虑:在视频流中比较当前帧和第一
帧而不是前一帧。如果没有物体在第一帧,比较当前
帧和第一帧将得出与运动速度无关的整个运动物体。
但该法也有一个很大的缺点,例如,如果第一帧有一
部汽车,然后它消失了,那么在有汽车的地方将一直
检测到有运动的情况。如果考虑更新第一帧来解决,
但第一帧不是静态背景的情形下,也不能得出很好的
结果。所以该法也不可行。
2.2改进算法
最有效的算法是基于建立所谓的情景背景并比
较每个当前帧和背景,即引入“背景帧”方法。有许
多方法重建睛景背景,但大部分都太复杂。这里将主
要描述重建背景的方法,该法相对简单并能很快实
现。
如前例所示,假设有一个24bpp RGB原始图像
称为当前帧(image),一个灰阶拷贝(currentFrame)
和一个灰阶背景帧,也用灰阶(backgroundFrame)表
示。首先,把视频流序列的第一帧作为背景帧,然后
比较当前帧和背景帧。但结果正如上面所描述的,并
不是我们想要的。我们的方法是根据设定的总值(这
里用每帧1级) “移动”背景帧到当前帧。因为需要
捕捉物体的运动方向,并做标记,所以沿着当前帧的
方向慢慢移动背景帧,通过每帧1级改变背景帧里像
素的颜色。
,/生成滤波器
MoveTowards moveTowaFilter=new MoveTowards();
,,沿着当前帧方向移动背景帧
moveTowaFilter.Oveflaylmage=currentFrame;
Bitmapmap=moveTowaF'dter.Apply(backgroundFrame);
注意释放旧背景帧。按照上面所使用的方法,仅稍微
扩展一下就可以得到如下结果:
,/生成处理滤波器序列
FiltersSequence procFilter=new FiltersSequence();
procFilter.Add(new Diference(backgroundFrame));
procFilter.Add(new Threshold(15,255));
procFilter.Add(new Opening());
procFilter.Add(new Edges());
,/使用滤波器
Bitmap tmpl=procFilter.Apply(currentFrame);
从图1可以看到,还是有一定的效果,它可以检
测到整个运动物体而不是仅仅运动物体的局部细节。
当然,检测结果尤其结果显示还不能令人满意。
图1改进算法结果示意图
2.3优化算法
基于优化的考虑还有另一个方法。以前面的例子
为例,不过这里是用Pixellate滤波当前帧和背景帧:
/FilterpixeF~ r=nCW Pixdlate();
Bitmap newlmage=pixeFilter(image);
这就有当前帧和背景帧的Pixellate版本,可按以
前沿着当前帧方向移动背景帧的处理方法,在主要处
理步骤中做一下改变, 即把procFilter.Add(new
Opening());改为procFilter.Add(new D~amfion());在
合并trnpl图像和原始图像的红色通道之后,获得如
图2所示图像。
图2优化算法结果示意图
从图2可以看到,结果看起来已经比较不错。在
照片中可以看到用曲线高亮显示运动的物体。
还可以参考下面的算法来获得个数、位置、宽和
高而不是高亮显示的物体运动。
(1)获得物体对象的矩形
BlobCounter.Get0bjectRectangles(thresholdedIm
age):
(2)从原始图像中生成Graphics图形对象
(3)画出每个矩形
(4)用高亮显示
图3是这个小代码的阀值滤波结果,效果看起来
还不错。
3运动物体的标识
有必要对检测到的运动物体做标识,增加运动标
识特性到这些运动检测算法中还是较容易的。前面算
法中都已经计算出当前帧和背景帧之间差异的二进
10
图3使用矩形及标识结果示意图
制图像,所以只需要在差异图像中计算出白像素的总
数即可,算法参考如下:
(1)计算白像素
private int CalculateWhitePixels(Bitmap image)
(2)锁定图像
BitmapData data=image.LockBits( new
Rectangle(0,0,width,height),
ImageLockMode.ReadOnly,
PixelFormat.Format8bpplndexed);
(3)根据图像长、宽来计算白像素的数量
data.ScanO.ToPointer():
for (int Y=0:Y<height:y++)
for (int X=0:X<width:x++,ptr++)
(4)解锁图像
(5)返回白像素的总数
不仅可以计算出白像素的总数,还可以计算每个
待检测物体的区域。如果计算出改变的总数大于预定
义值,就说明有运动物体需要标识。
小科_mrkj
学分:43 LV2
2010-07-26
地板
读者朋友:
    您好,非常高兴你能主动的去查找资料学习,希望以后继续关注我们的图书。
首页上一页 1 下一页尾页 3 条记录 1/1页
手机同步功能介绍
友情提示:以下图书配套资源能够实现手机同步功能
明日微信公众号
明日之星 明日之星编程特训营
客服热线(每日9:00-17:00)
400 675 1066
mingrisoft@mingrisoft.com
吉林省明日科技有限公司Copyright ©2007-2022,mingrisoft.com, All Rights Reserved长春市北湖科技开发区盛北大街3333号长春北湖科技园项目一期A10号楼四、五层
吉ICP备10002740号-2吉公网安备22010202000132经营性网站备案信息 营业执照