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

Photobucket

其實只要掌握住Kinect 那三大功能(彩色、深度影像和骨架追蹤),



Kinect  就可以玩出很多新花樣,一樣的,今天KT來介紹一個簡單入手的應用,

使用Kinect 彩色影像功能,讓Kinect變身為一台簡單相機,

可以拍照、調整上下視野角度。

設計畫面如下:
Photobucket
白框內:秀拍照時影像畫面

相機按鈕: 按下可以定格當下畫面

返回按鈕: 當按下相機按鈕後,會出現返回按鈕,
若不想此定格畫面,可以放棄返回繼續拍照。

儲存按鈕:可將當下定格的畫面儲成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 教學目錄

這個網誌中的熱門文章

2023 最新入門零基礎 Kotlin教學【從零開始學 Kotlin 程式設計】Kotlin 教學課程目錄 (Android Kotlin, IntelliJ IDEA, Android Studio, Android APP 開發教學)

最新入門零基礎 Java 教學【從零開始學 Java 程式設計】Java教學課程目錄 (IntelliJ IDEA 開發教學)

Android Studio 歷代版本下載點

nano 文字編輯器

2022 最新入門零基礎 Flutter教學 【Flutter 程式設計入門實戰 30 天】Flutter 教學課程目錄 (IntelliJ IDEA 開發教學)