Kinect 开发 —— 保持视频影像
相比直接将影像显示出来,如果能将录制到的影像保存到硬盘上就好了。但是,影像录制,是需要一定的技巧,在网上可以看到很多例子演示如何将Kinect获取到的影像以图片的形式保存到本地,前面的博文也介绍了这一点,但是你很少看到如何演示将一个完整的视频影像保存到本地硬盘上。幸运的是Emgu类库提供了一个VideoWriter类型来帮助我们实现这一功能。
下面的方法展示了Record和StopRecording方法如何将Kinect彩色影像摄像头产生的数据流保存到avi文件中。我们在D盘创建了一个vids文件夹,要写入avi文件之前需要保证该文件夹存在。当录制开始时,我们使用当前时间作为文件名创建一个文件,同时我们创建一个list对象来保存从彩色影像数据流中获取到的一帧帧影像。当停止录制时,将list对象中的一些列Emgu影像最为参数传入到VideoWriter对象来将这些影像转为为avi格式并保存到硬盘上。这部分代码没有对avi编码,所以产生的avi文件非常大。我们可以对avi文件进行编码压缩然后保存到硬盘上,但是这样会加大计算机的运算开销。
本例中,运动识别最后一点代码是简单的修改从彩色影像数据流“拉”取数据部分的逻辑。使得不仅将在探测到运动时将影像显示到UI界面上,同时也调用Record方法。当没有探测到运动时,UI界面上什么也不显示,并调用StopRecording方法。这部分代码也通过演示如何分析原始数据流,并探测Kinect视野中常用的变化给出了一个原型,这些变化信息可能会提供很有用的信息。
namespace KinectWriteToVideo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
KinectSensor _kinectSensor;
private MotionHistory _motionHistory;
private IBGFGDetector<Bgr> _forgroundDetector;
bool _isTracking = false; public MainWindow()
{
InitializeComponent(); this.Unloaded += delegate
{
_kinectSensor.ColorStream.Disable();
}; this.Loaded += delegate
{ _motionHistory = new MotionHistory(
1.0, //in seconds, the duration of motion history you wants to keep
0.05, //in seconds, parameter for cvCalcMotionGradient
0.5); //in seconds, parameter for cvCalcMotionGradient _kinectSensor = KinectSensor.KinectSensors[]; _kinectSensor.ColorStream.Enable();
_kinectSensor.Start(); BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (a, b) => Pulse();
bw.RunWorkerCompleted += (c, d) => bw.RunWorkerAsync();
bw.RunWorkerAsync();
};
} private void Pulse()
{
using (ColorImageFrame imageFrame = _kinectSensor.ColorStream.OpenNextFrame())
{
if (imageFrame == null)
return; using (Image<Bgr, byte> image = imageFrame.ToOpenCVImage<Bgr, byte>())
using (MemStorage storage = new MemStorage()) //create storage for motion components
{
if (_forgroundDetector == null)
{
_forgroundDetector = new BGStatModel<Bgr>(image
, Emgu.CV.CvEnum.BG_STAT_TYPE.GAUSSIAN_BG_MODEL);
} _forgroundDetector.Update(image); //update the motion history
_motionHistory.Update(_forgroundDetector.ForegroundMask); //get a copy of the motion mask and enhance its color
double[] minValues, maxValues;
System.Drawing.Point[] minLoc, maxLoc;
_motionHistory.Mask.MinMax(out minValues, out maxValues
, out minLoc, out maxLoc);
Image<Gray, Byte> motionMask = _motionHistory.Mask
.Mul(255.0 / maxValues[]); //create the motion image
Image<Bgr, Byte> motionImage = new Image<Bgr, byte>(motionMask.Size);
motionImage[] = motionMask; //Threshold to define a motion area
//reduce the value to detect smaller motion
double minArea = ; storage.Clear(); //clear the storage
Seq<MCvConnectedComp> motionComponents = _motionHistory.GetMotionComponents(storage);
bool isMotionDetected = false;
//iterate through each of the motion component
for (int c = ; c < motionComponents.Count(); c++)
{
MCvConnectedComp comp = motionComponents[c];
//reject the components that have small area;
if (comp.area < minArea) continue; OnDetection();
isMotionDetected = true;
break;
}
if (isMotionDetected == false)
{
OnDetectionStopped();
this.Dispatcher.Invoke(new Action(() => rgbImage.Source = null));
StopRecording();
return;
} this.Dispatcher.Invoke(
new Action(() => rgbImage.Source = imageFrame.ToBitmapSource())
); Record(imageFrame);
}
}
} DateTime _lastTracked = DateTime.Now;
private void OnDetection()
{
_lastTracked = DateTime.Now;
if (!_isTracking)
_isTracking = true;
} private void OnDetectionStopped()
{
var waitTime = ;
if (DateTime.Now.Subtract(_lastTracked) > TimeSpan.FromSeconds(waitTime))
_isTracking = false;
} bool _isRecording = false;
string _baseDirectory = @"d:\vids\";
string _fileName;
List<Image<Rgb, Byte>> _videoArray = new List<Image<Rgb, Byte>>(); void Record(ColorImageFrame image)
{
if (!_isRecording)
{
_fileName = string.Format("{0}{1}{2}", _baseDirectory, DateTime.Now.ToString("MMddyyyyHmmss"), ".avi");
_isRecording = true;
}
_videoArray.Add(image.ToOpenCVImage<Rgb, Byte>());
} void StopRecording()
{
if (!_isRecording)
return; CvInvoke.CV_FOURCC('P', 'I', 'M', ''); //= MPEG-1 codec
CvInvoke.CV_FOURCC('M', 'J', 'P', 'G'); //= motion-jpeg codec (does not work well)
CvInvoke.CV_FOURCC('M', 'P', '', '');//= MPEG-4.2 codec
CvInvoke.CV_FOURCC('D', 'I', 'V', ''); //= MPEG-4.3 codec
CvInvoke.CV_FOURCC('D', 'I', 'V', 'X'); //= MPEG-4 codec
CvInvoke.CV_FOURCC('U', '', '', ''); //= H263 codec
CvInvoke.CV_FOURCC('I', '', '', ''); //= H263I codec
CvInvoke.CV_FOURCC('F', 'L', 'V', ''); //= FLV1 codec using (VideoWriter vw = new VideoWriter(_fileName, , , , , true))
{
for (int i = ; i < _videoArray.Count(); i++)
vw.WriteFrame<Rgb, Byte>(_videoArray[i]);
}
_fileName = string.Empty;
_videoArray.Clear();
_isRecording = false; } }
}
Kinect 开发 —— 保持视频影像的更多相关文章
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- Kinect开发资源汇总
Kinect开发资源汇总 转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- Kinect 开发 —— 杂一
Kinect 提供了非托管(C++)和托管(.NET)两种开发方式的SDK,如果您用C++开发的话,需要安装Speech Runtime(V11),Kinect for Windows Runtime ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
- Kinect 开发 —— 全息图
Kinect的另一个有趣的应用是伪全息图(pseudo-hologram).3D图像可以根据人物在Kinect前面的各种位置进行倾斜和移动.如果方法够好,可以营造出3D控件中3D图像的效果,这样可以用 ...
- Kinect 开发 —— 进阶指引(上)
本文将会介绍一些第三方类库如何来帮助处理Kinect传感器提供的数据.使用不同的技术进行Kinect开发,可以发掘出Kinect应用的强大功能.另一方面如果不使用这些为了特定处理目的而开发的一些类库, ...
- Kinect开发 —— 基础知识
转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...
随机推荐
- iOS中关于字符 “&”的作用?
如NSFileManager中关于判断是否目录的 iOS中关于字符 "&"的作用? >> ios这个答案描述的挺清楚的:http://www.goodpm.ne ...
- Spring 注解拦截器使用详解
Spring mvc拦截器 平时用到的拦截器通常都是xml的配置方式.今天就特地研究了一下注解方式的拦截器. 配置Spring环境这里就不做详细介绍.本文主要介绍在Spring下,基于注解方式的拦截器 ...
- birthday
2.29 7.25 7.... 5... 10.01 02 03
- js相关禁止
遇到网页上有精美图片或者精彩文字想保存时,通常大家都是选中目标后按鼠标右键,在弹出菜单中选择“图片另存为”或“复制”来达到我们的目的.但是,目前有许多网页都屏蔽了鼠标右键,那么用js如何实现禁止鼠标右 ...
- 51Nod 和为k的连续区间
一整数数列a1, a2, ... , an(有正有负),以及另一个整数k,求一个区间[i, j],(1 <= i <= j <= n),使得a[i] + ... + a[j] = k ...
- vue的webpack打包
一个完整的项目离不开 开发环境 生产环境 测试环境 这三个环境 首先解释一下这三个环境的含义 开发环境:开发环境是程序猿们专门用于开发的服务器,配置可以比较随意,为了开发调试方便,一般打开全部错误报告 ...
- Conservative GC (Part two :MostlyCopyingGC )
目录 MostlyCopyingGC 概要 堆结构 分配 new_obj()函数 add_pages()函数 GC执行过程 mostly_copying()函数 promote_page()函数 pa ...
- 浴谷 P1768 天路
P1768 天路 题目描述 “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了. 和C_SUNSHINE大神商量后,这道猥琐的题目终于 ...
- hdu 1024 最大m子段和
注:摘的老师写的 最大m子段和问题 以-1 4 -2 3 -2 3为例最大子段和是:6最大2子段和是:4+(3-2+3)=8所以,最大子段和和最大m子段和不一样,不能用比如先求一个最大子段和,从序列中 ...
- Servlet之doPost获取表单参数
/** * 获取表单参数 */ private void readForm() { // TODO Auto-generated method stub Enumeration e = request ...