Thursday, October 22, 2015

การปรับองศาการก้มเงย (tilt) กล้อง Kinect

Kinect มีมอเตอร์ที่ฐานของกล้องเพื่อใช้ปรับมุมก้มเงยได้ โดยถ้ากล้องอยู่ในแนวราบ มุมปกติจะประมาณ 0 องศา และสามารถปรับเพิ่มมุมให้เงยขึ้นได้มากที่สุดไม่เกินค่า KinectSensor.MaxElevationAngle (ประมาณ +27 องศา) และปรับลดมุมให้ก้มลงได้ต่ำสุดไม่น้อยกว่าค่า KinectSensor.MinElevationAngle (ประมาณ -27 องศา)

การปรับมุมก้มเงยสามารถทำได้ง่ายๆ โดยการปรับค่า KinectSensor.ElevationAngle แต่มีข้อควรระวังว่า

  • ไม่ควรปรับเกิน 1 ครั้งต่อวินาที
  • ถ้าปรับต่อเนื่องกัน 15 ครั้ง ต้องพักมอเตอร์อย่างน้อย 20 วินาที มิฉะนั้นแล้วกล้องจะล็อคมอเตอร์ไปช่วงหนึ่ง
ทั้งนี้เนื่องมาจากมอเตอร์ของ Kinect ไม่ได้ออกแบบมาสำหรับการปรับบ่อยๆ ซึ่งอาจทำให้มอเตอร์เสื่อมหรือเสียหายได้

ดังนั้น การปรับมุมก้มเงยควรจะทำเมื่อมีความจำเป็น เช่น ผู้ใช้อยู่ในระยะที่กล้องตรวจจับได้ไม่ดี และไม่สามารถขอให้ผู้ใช้เคลื่อนย้ายตำแหน่งได้

ตัวอย่างผลลัพธ์ที่เราจะเขียนโค้ดกันครับ


เมื่อกดปุ่ม Down กล้องก็จะก้มลง


โค้ด UI
<Window x:Class="AdjustSensorAngle.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight" Loaded="Window_Loaded" >
    <StackPanel>
        <Image Name="kinectVideo" Width="320" Height="240"/>
        <TextBlock Name="txtAngle" Text="Current Angle" HorizontalAlignment="Center" FontSize="22" />
        <StackPanel Orientation="Horizontal" Margin="10" HorizontalAlignment="Center">           
            <Button Content="Up" Name="buttonUp" FontSize="22" MinWidth="100" Click="buttonUp_Click" />
            <Button Content="Down" Name="buttonDown" FontSize="22" MinWidth="100" Margin="10,0,0,0" Click="buttonDown_Click" />  
        </StackPanel>        
    </StackPanel>
</Window>
โค้ด C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Microsoft.Kinect;

namespace AdjustSensorAngle
{
    public partial class MainWindow : Window
    {
        KinectSensor myKinect;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (KinectSensor.KinectSensors.Count == 0)
            {
                MessageBox.Show("No Kinects detected", "Camera Viewer");
                Application.Current.Shutdown();
            }

            try
            {
                myKinect = KinectSensor.KinectSensors[0];

                myKinect.ColorStream.Enable();

                myKinect.Start();
            }
            catch
            {
                MessageBox.Show("Kinect initialise failed", "Camera Viewer");
                Application.Current.Shutdown();
            }

            //current angle
            txtAngle.Text = "Current angle = " + myKinect.ElevationAngle;

            myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);
        }//end Window_Loaded method

        private void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
            {
                if (colorFrame == null) 
                    return;

                byte[] colorData = new byte[colorFrame.PixelDataLength];
                colorFrame.CopyPixelDataTo(colorData);

                kinectVideo.Source = BitmapSource.Create(
                                    colorFrame.Width, colorFrame.Height, // image dimensions
                                    96, 96,  // resolution - 96 dpi for video frames
                                    PixelFormats.Bgr32, // video format
                                    null,               // palette - none
                                    colorData,          // video data
                                    colorFrame.Width * colorFrame.BytesPerPixel // stride
                                    );
            }
        }//end ColorFrameReady method

        //============== Up and Down button click methods ===================
        private void buttonUp_Click(object sender, RoutedEventArgs e)
        {
            int angle = myKinect.ElevationAngle;
            angle += 5;
            if (angle <= myKinect.MaxElevationAngle)
            {
                //tilt the camera up 5 degrees
                myKinect.ElevationAngle = angle;
                txtAngle.Text = "Current angle = " + angle;
            }
        }

        private void buttonDown_Click(object sender, RoutedEventArgs e)
        {
            int angle = myKinect.ElevationAngle;
            angle -= 5;
            if (angle >= myKinect.MinElevationAngle)
            {
                //tilt the camera down 5 degrees
                myKinect.ElevationAngle = angle;
                txtAngle.Text = "Current angle = " + angle;
            }
        }
    }
}

1 comment:

  1. โคตร ขอบคุณพี่มากเลย ขอบคุณครับ รักเลย

    ReplyDelete