每個 Kinect 應用都包含基本步驟:偵測並發現連接的 Kinect 感測器、初始化感測器與所需資料流、處理產生的資料、最後正確釋放資源。本文將詳細說明感測器發現、初始化、啟動與釋放,並以 ColorImageStream 為例示範彩色影像資料的取得與顯示。
KinectSensor 直接代表實體硬體,是取得彩色、景深、骨架三大資料流的入口。SDK 透過靜態屬性 KinectSensor.KinectSensors(KinectSensorCollection)管理所有連接裝置。集合提供 StatusChanged 事件通知裝置連接狀態變化。
感測器狀態枚舉:Connected、Disconnected、NotReady、NotPowered、Error、Initializing。僅 Connected 狀態可初始化。
發現並追蹤感測器的標準模式:
public partial class MainWindow : Window {
private KinectSensor kinect;
public KinectSensor Kinect {
get { return kinect; }
set {
if (kinect != value) {
if (kinect != null) { UninitializeKinectSensor(kinect); kinect = null; }
if (value != null && value.Status == KinectStatus.Connected) {
kinect = value; InitializeKinectSensor(kinect);
}
}
}
}
public MainWindow() {
InitializeComponent();
Loaded += (s, e) => DiscoverKinectSensor();
Unloaded += (s, e) => Kinect = null;
}
private void DiscoverKinectSensor() {
KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
Kinect = KinectSensor.KinectSensors.FirstOrDefault(s => s.Status == KinectStatus.Connected);
}
private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e) {
switch (e.Status) {
case KinectStatus.Connected:
if (kinect == null) kinect = e.Sensor; break;
case KinectStatus.Disconnected:
if (kinect == e.Sensor) {
kinect = null;
kinect = KinectSensor.KinectSensors.FirstOrDefault(s => s.Status == KinectStatus.Connected);
if (kinect == null) { /* 通知使用者重新插入 */ }
} break;
// 其他狀態處理...
}
}
}
關鍵點:以屬性封裝私有欄位,確保只接受 Connected 狀態的感測器;Loaded/Unloaded 對應初始化與釋放;StatusChanged 處理熱插拔。
初始化包含三步驟:
ColorStream.Enable()、DepthStream.Enable()、SkeletonStream.Enable())。FrameReady 事件(ColorFrameReady、DepthFrameReady、SkeletonFrameReady)或 AllFramesReady。kinectSensor.Start() 開始產生幀資料。private void InitializeKinectSensor(KinectSensor kinectSensor) {
if (kinectSensor != null) {
kinectSensor.ColorStream.Enable();
kinectSensor.ColorFrameReady += Kinect_ColorFrameReady;
kinectSensor.Start();
}
}
private void UninitializeKinectSensor(KinectSensor kinectSensor) {
if (kinectSensor != null) {
kinectSensor.Stop();
kinectSensor.ColorFrameReady -= Kinect_ColorFrameReady;
}
}
注意:釋放時應先 Stop() 再移除事件訂閱,切勿呼叫 Dispose(),否則需重新插拔裝置才能再次取得。
Kinect 擁有紅外與彩色兩組攝像頭。彩色攝像頭提供一般網路攝像頭相似的 RGB 影像,設定最簡單。
XAML 介面:
<Window ...>
<Grid>
<Image x:Name="ColorImageElement" />
</Grid>
</Window>
事件處理:取得 ColorImageFrame,複製像素資料至位元組陣列,再以 BitmapImage.Create 產生影像來源:
void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) {
using (ColorImageFrame frame = e.OpenColorImageFrame()) {
if (frame != null) {
byte[] pixelData = new byte[frame.PixelDataLength];
frame.CopyPixelDataTo(pixelData);
ColorImageElement.Source = BitmapImage.Create(
frame.Width, frame.Height, 96, 96,
PixelFormats.Bgr32, null,
pixelData, frame.Width * frame.BytesPerPixel);
}
}
}
執行結果:

本文涵蓋 Kinect 感測器發現、狀態監控、初始化/釋放流程,以及彩色影像串流的基本取得與顯示。由於預設 30 FPS 會頻繁建立 Bitmap 物件,下一篇將介紹 WriteableBitmap 優化記憶體使用,並比較事件模式與輪詢模式的取捨。
範例程式碼:下載連結