承接上篇「近距離模式、擴展方法庫、影像轉換」基礎,本文深入四大進階專題:基於EmguCV的運動檢測與視頻錄製、Haar特徵人臉識別、WPF 3D偽全息圖實現、以及FAAST/Unity3D/Microsoft Robotics三大生態工具鏈介紹,為Kinect深度應用開發提供完整技術棧參考。
固定背景差分易受光照、擺動干擾。採用 EmguCV BGStatModel (Gaussian Mixture Model) 持續更新背景模型,配合 MotionHistory 追蹤運動軌跡,通過連通分量面積過濾噪聲。
namespace ImageManipulationExtensionMethods {
public static class EmguImageExtensions {
// Kinect ColorImageFrame -> Emgu Image
public static Image ToOpenCVImage(this ColorImageFrame image)
where TColor : struct, IColor where TDepth : new() {
return new Image(image.ToBitmap());
}
// System.Drawing.Bitmap -> Emgu Image
public static Image ToOpenCVImage(this Bitmap bitmap)
where TColor : struct, IColor where TDepth : new() {
return new Image(bitmap);
}
// Emgu IImage -> WPF BitmapSource
public static BitmapSource ToBitmapSource(this IImage image) {
return image.Bitmap.ToBitmapSource();
}
}
}
避免事件驅動導致UI線程阻塞,採用後台線程輪詢 OpenNextFrame:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (a, b) => Pulse();
bw.RunWorkerCompleted += (c, d) => bw.RunWorkerAsync(); // 循環
bw.RunWorkerAsync();
private MotionHistory _motionHistory = new MotionHistory(1.0, 0.05, 0.5); // 歷史時長、梯度參數
private IBGFGDetector _forgroundDetector;
private void Pulse() {
using (ColorImageFrame frame = _kinectSensor.ColorStream.OpenNextFrame(200)) {
if (frame == null) return;
using (Image image = frame.ToOpenCVImage())
using (MemStorage storage = new MemStorage()) {
if (_forgroundDetector == null)
_forgroundDetector = new BGStatModel(image, Emgu.CV.CvEnum.BG_STAT_TYPE.GAUSSIAN_BG_MODEL);
_forgroundDetector.Update(image); // 更新背景模型
_motionHistory.Update(_forgroundDetector.ForgroundMask); // 更新運動歷史
// 運動掩碼增強顯示
double[] minV, maxV; Point[] minL, maxL;
_motionHistory.Mask.MinMax(out minV, out maxV, out minL, out maxL);
Image motionMask = _motionHistory.Mask.Mul(255.0 / maxV[0]);
Image motionImage = new Image(motionMask.Size);
motionImage[0] = motionMask;
// 連通分量分析,過濾微小噪聲
storage.Clear();
Seq components = _motionHistory.GetMotionComponents(storage);
bool motionDetected = false;
for (int c = 0; c < components.Count; c++) {
if (components[c].area < 100) continue; // 面積閾值
OnDetection(); motionDetected = true; break;
}
if (!motionDetected) {
OnDetectionStopped();
Dispatcher.Invoke(() => rgbImage.Source = null);
StopRecording();
return;
}
Dispatcher.Invoke(() => rgbImage.Source = frame.ToBitmapSource());
Record(frame); // 運動時錄製
}
}
}
bool _isRecording = false; string _baseDir = @"d:\vids\"; List> _videoFrames = new List>();
void Record(ColorImageFrame frame) {
if (!_isRecording) { _fileName = _baseDir + DateTime.Now.ToString("MMddyyyyHmmss") + ".avi"; _isRecording = true; }
_videoFrames.Add(frame.ToOpenCVImage());
}
void StopRecording() {
if (!_isRecording) return;
// FourCC 編碼:MJPG, MPEG4, DIVX, H263 等
using (VideoWriter vw = new VideoWriter(_fileName, 0, 30, 640, 480, true)) {
foreach (var img in _videoFrames) vw.WriteFrame(img);
}
_videoFrames.Clear(); _isRecording = false;
}

Viola-Jones 框架 + Haar-like 特徵 + AdaBoost 訓練級聯分類器,OpenCV/EmguCV 內置 haarcascade_frontalface_default.xml 模型,運算量小、適合實時。
String faceFileName = "haarcascade_frontalface_default.xml";
public void Pulse() {
using (HaarCascade face = new HaarCascade(faceFileName)) {
var frame = _kinectSensor.ColorStream.OpenNextFrame(100);
var image = frame.ToOpenCVImage();
using (Image gray = image.Convert()) {
gray._EqualizeHist(); // 直方圖均衡化增強對比度
// 檢測參數:scaleFactor=1.1, minNeighbors=10, flags=DO_CANNY_PRUNING, minSize=20x20
MCvAvgComp[] faces = face.Detect(gray, 1.1, 10, HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
foreach (var f in faces) image.Draw(f.rect, new Rgb(Color.Blue), 2); // 畫藍框
Dispatcher.BeginInvoke(() => rgbImage.Source = image.ToBitmapSource());
}
}
}

Image laughingMan = new Image("laughing_man.jpg");
foreach (var f in faces) {
var rect = new Rectangle(f.rect.X - f.rect.Width/2, f.rect.Y - f.rect.Height/2, f.rect.Width*2, f.rect.Height*2);
var resized = laughingMan.Resize(rect.Width, rect.Height, INTER.CV_INTER_LINEAR);
for (int y = 0; y < rect.Height; y++)
for (int x = 0; x < rect.Width; x++)
if (resized[y, x].Blue != 0 && resized[y, x].Red != 0 && resized[y, x].Green != 0) // 簡單非透明判斷
image[y + rect.Y, x + rect.X] = resized[y, x];
}

引用《攻殼機動隊》笑臉繞過監控隱喻,展示臉部檢測精度遠超骨骼頭部節點推算。
根據用戶相對 Kinect 的 3D 位置 (X,Y,Z),實時移動 Viewport3D.Camera (PerspectiveCamera) 位置並保持看向原點,產生 3D 物體隨視角旋轉/縮放的全息感。單用戶場景有效。
模型數據可用 Blender 建模導出 XAML(需插件),或手工編寫簡單幾何體。
void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) {
float x=0, y=0, z=0;
using (var frame = e.OpenSkeletonFrame()) {
if (frame == null) return;
var skeletons = new Skeleton[frame.SkeletonArrayLength];
frame.CopySkeletonDataTo(skeletons);
foreach (var s in skeletons) {
if (s.TrackingState == SkeletonTrackingState.Tracked) {
x = s.Position.X * 60; // 單位換算:米 -> 視景單位
z = s.Position.Z * 120;
y = s.Position.Y;
break;
}
}
}
if (Math.Abs(x) > 0) {
camera.Position = new Point3D(x, y, z);
camera.LookDirection = new Vector3D(-x, -y, -z); // 始終看向原點
}
}

延伸:將立方體 Z 軸拉伸為矩形牆面,排布多塊不同顏色/位置的矩形,構建全息牆面矩陣。

| 工具/平台 | 核心價值 | 官網/資源 |
|---|---|---|
| FAAST (Flexible Action and Articulated Skeleton Toolkit) | 手勢映射中間件:將 Kinect 骨骼手勢映射為鍵盤/鼠標/遊戲手柄輸入,支持《使命召喚》《魔獸世界》《Second Life》等遊戲體感操作。正移植至官方 SDK。 | https://projects.ict.usc.edu/mxr/faast |
| Unity3D | 跨平台 3D 遊戲/應用引擎,資產商店豐富 Kinect 插件,支持發布 Win/Mac/iOS/Android/WebGL/Xbox/PS/Wii,極大降低 3D 體感應用開發門檻。 | https://unity3d.com |
| Microsoft Robotics Developer Studio (RDS 4.0) | 機器人開發平台,集成 Kinect 避障、導航、人機交互服務,支持專用機器人硬體平台(如 Eddie, TurtleBot)。 | https://www.microsoft.com/robotics |
WriteableBitmap 替代 BitmapSource 減少內存拷貝using 包裹所有 EmguCV Image/MemStorage本文串聯「運動檢測→視頻存證→人臉識別→AR貼圖→偽全息圖」五大進階能力,均基於 Kinect 原始流 + 開源庫 組合實現,展示了 Kinect 作為「三維感知輸入設備」的擴展性邊界。配合 FAAST/Unity3D/RDS 三大生態,開發者可快速構建體感遊戲、互動展項、機器人視覺、AR試妝、安防監控等多元化應用。代碼性能優化空間大,歡迎同行交流改進。
作者:yangecnu | 出處:https://www.cnblogs.com/yangecnu/