如何使用 Kinect 來拍照,儲存彩色影像圖片(For Windows SDK V1)

其實只要掌握住Kinect 那三大功能(彩色、深度影像和骨架追蹤),
Kinect 就可以玩出很多新花樣,一樣的,今天KT來介紹一個簡單入手的應用,
使用Kinect 彩色影像功能,讓Kinect變身為一台簡單相機,
可以拍照、調整上下視野角度。
設計畫面如下:

白框內:秀拍照時影像畫面
相機按鈕: 按下可以定格當下畫面
返回按鈕: 當按下相機按鈕後,會出現返回按鈕,
若不想此定格畫面,可以放棄返回繼續拍照。
儲存按鈕:可將當下定格的畫面儲成Jpeg圖片格式。
上下滑桿:上下調整想要的角度後,按下"設定"按鈕,即可調整上下視野角度 。
影片教學:
當按下快門拍照時,停止彩色影像擷取,使畫面停格,卸載Kinect裝置:
//關閉 Kinect裝置
private void UninitiaKinect()
{
if (sensor == null)
{
return;
}
sensor.ColorFrameReady -= runtime_VideoFrameReady;
sensor.Stop();
sensor.AudioSource.Stop();
sensor = null;
}
當按下返回時,彩色影像繼續擷取當下即時動態畫面,重新初始化Kinect裝置:
//初始化 Kinect裝置
private void InitialKinect()
{
Save.Visibility = Visibility.Hidden;
if (sensor != null)
{
UninitiaKinect();
}
sensor = KinectSensor.KinectSensors[0];
//
sensor.Start();
sensor.ColorFrameReady += runtime_VideoFrameReady;
sensor.ColorStream.Enable();
}
儲存照片,將目前停格的畫面轉成Jpeg圖檔,然後選擇位置儲存下來:
(程式碼引用參考:Ouch@點部落)
//儲存照片處理函數
private void Btn_Save(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//將點陣圖(Bitmap)存成Jpeg圖檔格式(程式碼引用"Ouch@點部落")
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(BitmapFrame.Create(videoImage.Source as BitmapSource)));
Microsoft.Win32.SaveFileDialog openFileDialog = new Microsoft.Win32.SaveFileDialog();
openFileDialog.FileName = "Image";
openFileDialog.DefaultExt = ".jpg";
openFileDialog.Filter = "Jpeg Image (.jpg)|*.jpg";
Nullable result = openFileDialog.ShowDialog();
string fileName = string.Empty;
if (result == true)
{
fileName = openFileDialog.FileName;
}
else
{
return;
}
using (var stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
程式碼完整解說,請參考影片教學和程式碼中的註解說明。
Xaml CODE:
C# CODE:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;
using System.IO;
namespace KinectTakePicture_Demo
{
public partial class MainWindow : Window
{
//宣告Kinect裝置變數名稱
KinectSensor sensor=null;
byte[] pixelData;
public MainWindow()
{
InitializeComponent();
//宣告視窗載入與卸載事件
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
this.Unloaded += new RoutedEventHandler(MainWindow_Unloaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
InitialKinect();//當視窗載入時,初始化 Kinect裝置
}
void MainWindow_Unloaded(object sender, RoutedEventArgs e)
{
UninitiaKinect();//視窗關閉時,關閉 Kinect裝置
}
//初始化 Kinect裝置
private void InitialKinect()
{
Save.Visibility = Visibility.Hidden;
if (sensor != null)
{
UninitiaKinect();
}
sensor = KinectSensor.KinectSensors[0];
//
sensor.Start();
sensor.ColorFrameReady += runtime_VideoFrameReady;
sensor.ColorStream.Enable();
}
//關閉 Kinect裝置
private void UninitiaKinect()
{
if (sensor == null)
{
return;
}
sensor.ColorFrameReady -= runtime_VideoFrameReady;
sensor.Stop();
sensor.AudioSource.Stop();
sensor = null;
}
//彩色影像處理函數
void runtime_VideoFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
bool receivedData = false;
using (ColorImageFrame CFrame = e.OpenColorImageFrame())
{
if (CFrame == null)
{
// The image processing took too long. More than 2 frames behind.
}
else
{
pixelData = new byte[CFrame.PixelDataLength];
CFrame.CopyPixelDataTo(pixelData);
receivedData = true;
}
}
if (receivedData)
{ //將彩色影像資料,轉成點陣圖(Bitmap)
BitmapSource source = BitmapSource.Create(640, 480, 96, 96,
PixelFormats.Bgr32, null, pixelData, 640 * 4);
//將Bitmap 影像秀到Image控制項上
videoImage.Source = source;
}
}
//拍照按鈕按下處理函數
private void Btn_Shoot(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sensor == null)
{
SetShootImage(0);//設定拍照按鈕為"相機"圖案
InitialKinect();
//開啟調整Kinect角度功能
Btn_AdjustAngle.IsEnabled = true;
slider1.IsEnabled = true;
}
else
{
//Camera_ Sound.wav 放在 bin資料夾
MediaPlayer player = new MediaPlayer();
player.Open(new Uri("Camera_ Sound.wav", UriKind.Relative));
player.Play();//播放拍照時的快門聲音
SetShootImage(1);//設定拍照按鈕為"返回"圖案
UninitiaKinect();
//關閉調整Kinect角度功能
Btn_AdjustAngle.IsEnabled = false;
slider1.IsEnabled = false;
}
}
//===設定 Shoot 狀態圖片===Start===
void SetShootImage(int State)
{
// Create source.
BitmapImage bi = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block.
bi.BeginInit();
if (State == 0)
{
//未 Shoot,秀shoot
Save.Visibility = Visibility.Hidden;
bi.UriSource = new Uri(@"/Resources/Shoot.png", UriKind.RelativeOrAbsolute);
}
else if (State == 1)
{
//已 Shoot,秀return
Save.Visibility = Visibility.Visible;
bi.UriSource = new Uri(@"/Resources/Return.png", UriKind.RelativeOrAbsolute);
}
bi.EndInit();
// Set the image source.
Shoot.Source = bi;
}
//儲存照片處理函數
private void Btn_Save(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//將點陣圖(Bitmap)存成Jpeg圖檔格式(程式碼引用"Ouch@點部落")
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(BitmapFrame.Create(videoImage.Source as BitmapSource)));
Microsoft.Win32.SaveFileDialog openFileDialog = new Microsoft.Win32.SaveFileDialog();
openFileDialog.FileName = "Image";
openFileDialog.DefaultExt = ".jpg";
openFileDialog.Filter = "Jpeg Image (.jpg)|*.jpg";
Nullable result = openFileDialog.ShowDialog();
string fileName = string.Empty;
if (result == true)
{
fileName = openFileDialog.FileName;
}
else
{
return;
}
using (var stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
private void AdjustAngle(object sender, RoutedEventArgs e)
{
Btn_AdjustAngle.IsEnabled = false;//將按鈕設為失能(Disable),等角度整套設定完再致能(Enabled)
//設定角度
if (sensor != null && sensor.IsRunning)
{
//將滑桿的值存到 ElevationAngle
sensor.ElevationAngle = (int)slider1.Value;
}
Btn_AdjustAngle.IsEnabled = true;//恢復按鈕設定功能
}
}
}
範例程式碼下載:
相關文章參考:
HKT線上教學教室 - Kinect 教學目錄
