星期四, 3月 15, 2012

如何使用 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 教學目錄

4 則留言 :

  1. 版主你好:

    我想請問如果想將Kinect 攝影機所捕捉的畫面,儲存成影片 .avi或其他格式,是否有辦法辦到呢?

    因為網上找了很多資料都是將畫面停止,然後將該畫面存成圖片,

    不知是否有辦法將影像錄製下來呢? 謝謝。

    回覆刪除
  2. 哈囉~憲祥,

    當然可以將影像錄製成.avi格式喔!!!

    有很多種作法,KT這邊是用Emgu CV 裡的VideoWriter,

    你可以搜尋 "Emgu VideoWriter",應該可以找到滿山滿谷的範例喔!!!

    回覆刪除
  3. 哈囉~憲祥,

    這篇文章:

    如何使用 Kinect 來錄影,錄製儲存彩色影片(For Windows SDK V1)
    http://tw-hkt.blogspot.com/2012/04/kinect-for-windows-sdk-v1_15.html

    希望對你有幫助

    回覆刪除
  4. 請問一下
    它在拍照後一定要另存新檔嗎?
    可不可以直接讓它自動預設在桌面或路徑呢?

    回覆刪除

回覆意見時,麻煩輸入一下暱稱
(隨便取個名字也好~ ^_^)
好讓我方便回覆您的問題,
選擇「名稱/網址」輸入您的暱稱,
麻煩一下,謝謝大家。

關閉廣告 [X]