# kinecMonitor **Repository Path**: li022721/kinecMonitor ## Basic Information - **Project Name**: kinecMonitor - **Description**: 基础---试试openCV实例代码,只写了部分,完善后可用作家庭监控系统(加点点代码就得了,我懒得做了)核心代码已经完成:kinect识别人体(有红外摄像头,晚上也不怕妈妈进房间啦),有人出入kinect视野区域,则每150帧数据(大概5秒)保存一段视频录像。测试已通过 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2024-05-11 - **Last Updated**: 2024-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # kinectMonitor #### 介绍 基于kinect的家庭监控系统,主要是为了监控我爸爸是不是趁我上班进我房间,偷我的ukelele拍抖音 使用了计算机视觉库openCV #### 软、硬件架构 - 硬件: - kinect(我用的xbox1.0版本,2.0网上资料要多一点,一代很多接口也变了,很难排错) - 一台电脑(配置要好) - 软件:我用的vs开发,wpf应用 - 开发语言:c# #### 项目说明 - openCV是c++编写的,此项目基于c#开发,用到的库是emguCV(封装了openCV),另外还有一个库叫 openCvSharp也是可以的。 EmguCV的官方网站 [EmguCV的官方网站](http://www.emgu.com/wiki/index.php/Main_Page) EmguCV源代码和安装包[EmguCV源代码和安装包](http://sourceforge.net/projects/emgucv/files/ ) - 每一种类库都有自己能够理解的核心图像模型,在EmguCV中也就是Image,泛型类型,他实现了Emgu.CV.IImage接口。 本项目用到的一个类EmguImageExtensions,该类作为一个扩展方法实现了我们熟悉的一些影像数据格式和Emgu特定的影像格式之间的转换。用到这里,主要是为了将kinect中的彩色图像帧转换为openCV图像。网上找的这个有点问题,kinect的图像帧没有提供toBitMap方法,可能二代就有了?我大概重新把这个方法代码了一下,测试通过了,注释掉了最后一个方法,Image并没有实现IImage接口,不晓得怎么改,反正我也用不着,就算了把。 > 改之后 ``` namespace ImageManipulationExtensionMethods { public static class EmguImageExtensions { // 将kinect中的彩色图像帧转换为openCV图像,这里是我改过的,源码附在下方,可能版本的不同,自行选择 public static Image ToOpenCVImage(this ColorImageFrame image) where TColor : struct, IColor where TDepth : new() { byte[] pixels = new byte[image.PixelDataLength]; image.CopyPixelDataTo(pixels); Bitmap bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppRgb); //锁定到系统内存中 BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); //bitmapData.Scan0是指向存放图像像素的第一个内存地址,即第一个像素点的值,同样也可以通过bitmap.GetPixel(0, 0) //来获得。因为计算机屏幕坐标轴是在左上角向右下方延伸的,所以bitmapData.Scan0表示的是左上角第一个像素点 //IntPtr:平台特定的整数类型 IntPtr ptr = bitmapData.Scan0; //转换 Marshal.Copy(pixels, 0, ptr, image.PixelDataLength); bitmap.UnlockBits(bitmapData); return new Image(bitmap); } public static Image ToOpenCVImage(this Bitmap bitmap) where TColor : struct, IColor where TDepth : new() { return new Image(bitmap); } //public static System.Windows.Media.Imaging.BitmapSource ToBitmapSource(this IImage image) //{ // var source = image.Bitmap.ToBitmapSource(); // return source; //} } } ``` > 原始代码 ``` namespace ImageManipulationExtensionMethods { public static class EmguImageExtensions { public static Image ToOpenCVImage(this ColorImageFrame image) where TColor : struct, IColor where TDepth : new() { var bitmap = image.ToBitmap(); return new Image(bitmap); } public static Image ToOpenCVImage(this Bitmap bitmap) where TColor : struct, IColor where TDepth : new() { return new Image(bitmap); } public static System.Windows.Media.Imaging.BitmapSource ToBitmapSource(this IImage image) { var source = image.Bitmap.ToBitmapSource(); return source; } } } ``` - 核心代码 录制并保存视频 ``` //录制视频 private void DispatchVideoRecording(ColorImageFrame colorImageFrame) { if (isBodyDetected && null != colorImageFrame) { //搞不出来了 //byte[] pixel = new byte[_kinect.colorstream.framepixeldatalength]; //colorimageframe.copypixeldatato(pixel); //image frame = new image(colorimageframe.width, colorimageframe.height); //frame.bytes = pixel; VidioArray.Add(colorImageFrame.ToOpenCVImage()); } else { VidioArray.Clear(); } //录制视频 if (VidioArray.Count > ClipMaxFrameNum) { String fileName = "clip" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".avi"; System.Drawing.Size size = new System.Drawing.Size(640,480); using (VideoWriter vm = new VideoWriter(fileName,30,size, true)) { for (int i = 0; i < VidioArray.Count(); i++) { vm.Write(VidioArray[i].Mat); } } VidioArray.Clear(); } } ``` #### 实现逻辑 1、用kinect来识别视野范围的人体,基于kinect的深度图,可以确定视野范围中是否出现了人物,并发出检测到人体的信号 *(当然也可以是其他运动的物体,不过识别人体以外的运动物体要用另外的库来做,kinect没有接口可调,例如OpenCv可以用作面部识别,手势识别,运动物体识别等)* 2、打开kinect的彩色图像流,当收到kinect发出的检测到人体的信号时,将彩色图像帧逐帧保存到队列中(队列大小为150),kinect目前大概是一秒返回30帧,所以这个队列帧可以接收5秒的数据,判断当队列满时,将队列帧数据提取保存成.avi格式的视频文件,存到磁盘。 3、以上信号在程序中可用全局变量表示,具体见代码。 4、这样做可以保证录制下来的视频,都是有内容的,不至于一段家庭监控录像,晚上8小时全是空白,看的也瘆人。 4、基本上就完成了一个自动检测人体并保存录像的功能。我准备晚上放到客厅,看看晚上有没有骇人的事情发生,早上起来看,又是惊喜刺激的一天呢。