Monday, April 13, 2015

การตรวจสอบความผิดพลาดจากการเชื่อมต่อกับ Kinect

ตอนที่แล้วเราได้ลองเขียนโปรแกรมเพื่อเชื่อมต่อกับ Kinect แล้วดึงภาพจากกล้องมาแสดงผล

จะเกิดอะไรขึ้นถ้า Kinect ไม่ได้ต่ออยู่ หรือแม้ว่าต่ออยู่ แต่ไม่สามารถเชื่อมต่อได้

แน่นอนว่าโปรแกรมก็จะผิดพลาดแล้วจบไปแบบไม่สวย ทำอย่างไรให้โปรแกรมแจ้งเตือนแล้วค่อยปิดไปแบบนี้

ลองมาเขียนโค้ดตรวจสอบข้อผิดพลาดในการเชื่อมต่อเหล่านี้กันดีกว่าครับ โดยฟังก์ชันที่ต้องไปแก้ไข ก็คือ Window_Loaded() ที่จะถูกเรียกเมื่อหน้าต่างของโปรแกรมถูกสร้างขึ้น

ความผิดพลาดจากการเชื่อมต่อ ตามตำราบอกไว้ว่าอาจเกิดได้สองกรณี คือ
1. ไม่ได้ต่อ Kinect หรือการเชื่อมต่อไม่สมบูรณ์ (เช่นยังไม่ได้ติดตั้ง driver)
อันนี้เราสามารถเช็คได้โดยใช้คำสั่ง KinectSensor.KinectSensors.Count ซึ่งจะบอกว่าตอนนี้มี Kinect ต่อกับคอมของเรากี่อัน (สูงสุดได้ 4 อัน) ถ้าได้ค่า 0 แสดงว่าไม่มี Kinect ต่ออยู่เลย

2. เชื่อมต่อ Kinect ได้ แต่ไม่สามารถเรียกใช้งานได้ ซึ่งอาจเกิดจาก มีแอพอื่นใช้กล้องอยู่ หรือ memory ไม่พอ เป็นต้น
สามารถตรวจสอบได้โดยใช้ try...catch ครอบคำสั่งที่ลองติดต่อ Kinect ได้แก่ KinectSensor.KinectSensors[0] และ myKinect.Start() เป็นต้น

เรามาลองตรวจจับเหตุการณ์ข้างต้น โดยการแก้ไขเฉพาะฟังก์ชัน Window_Loaded() ดังนี้ครับ

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            //Check if there is any connecting Kinect
            if (KinectSensor.KinectSensors.Count == 0)
            {
                MessageBox.Show("No Kinect detected!", "Error");
                //end this app
                Application.Current.Shutdown();
            }

            //Try to initialize Kinect
            try
            {
                //Get the first Kinect connected to this computer
                myKinect = KinectSensor.KinectSensors[0];
                //Enable the color video stream
                myKinect.ColorStream.Enable();
                //Start the sensor
                myKinect.Start();
            }
            catch
            {
                MessageBox.Show("Initialize Kinect failed!", "Error");
                //end this app
                Application.Current.Shutdown();
            }

            //Video event handler
            myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);           
        }

Sunday, April 12, 2015

การอ่านและแสดงผลภาพจาก Kinect

ลองมาเขียนโค้ดเชื่อมต่อกับ Kinect เพื่อแสดงผลวิดีโอจากกล้อง ประมาณรูปด้านล่างกันครับ

อันดับแรก เปิด Visual Studio ก่อน เปิดกล้องและเสียบเชื่อมต่อกับพอร์ต USB ให้เรียบร้อย

สร้างโปรเจคใหม่ของ C# สมมติว่าใช้ชื่อว่า KinectCam

ลองสังเกตดูแถบ Solution Explorer ซึ่งอาจจะอยู่ทางด้านขวามือ คลิกขวาที่ References แล้วเลือก Add Reference


เลือกหัวข้อ Browse แล้วเลือกปุ่ม Browse... ด้านล่างเพื่อหาไฟล์ Microsoft.Kinect.dll ซึ่งจะอยู่ที่ C:\Program Files\Microsoft SDKs\Kinect\v1.8\Assemblies ถ้าติดตั้งตามปกติ จะได้ผลลัพธ์ดังภาพ

ที่ Solution explorer ดับเบิลคลิกที่ MainWindow.xaml.cs เพื่อจะเขียนโค้ด

ที่ Solution explorer ดับเบิลคลิกที่ MainWindow.xaml เพื่อจะแก้ไข หน้านี้จะเป็น Interface หลักของโปรแกรม

ให้เพิ่มแท็กชื่อ Image เพื่อจะแสดงวิดีโอจาก Kinect ลงบนหน้าต่างดังนี้

"< Image Name="kinectVideo" Width="640" Height="480" />"

ต่อไป ให้ทำการคลิกบริเวณโค้ดที่เขียนว่า "< Window x:Class=... " จากนั้นก็เลื่อนไปดูทางขวามือ ในส่วนของแถบ Properties ให้คลิกสัญลักษณ์ที่เป็นเหมือนสายฟ้า แล้วเลื่อนหา Event ชื่อ Loaded จากนั้นก็ดับเบิลคลิกในช่องว่างที่อยู่ถัดจาก Event Loaded นี้ มันก็จะเกิด Method ใหม่ขึ้นมาชื่อ Window_Loaded_1 โดยอัตโนมัติในไฟล์โค้ด MainWindow.xaml.cs ในที่นี้ ผมเปลี่ยนให้เป็นชื่อ Window_Loaded ทั้งในส่วนของการออกแบบ และส่วนโค้ด




จากนั้น เราก็จะทำการเพิ่มโค้ดต่างๆ ดังนี้

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 KinectCam
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        KinectSensor myKinect;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //Get the first Kinect connected to this computer
            myKinect = KinectSensor.KinectSensors[0];
            //Enable the color video stream
            myKinect.ColorStream.Enable();
            //Video event handler
            myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);
            //Start the sensor
            myKinect.Start();
        }

        void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
            {
                //if get new video frame
                if (colorFrame == null)
                    return;
                //create an array of pixel data
                byte[] colorData = new byte[colorFrame.PixelDataLength];
                //extract pixel data from the frame to the array
                colorFrame.CopyPixelDataTo(colorData);
                //create a bitmap from the video array and set it to Image UI
                kinectVideo.Source = BitmapSource.Create(
                    colorFrame.Width, colorFrame.Height,    //image dimension
                    96, 96,                 //resolution 96 dpi for video frames
                    PixelFormats.Bgr32,     //image format
                    null,                   //palette - none
                    colorData,              //video data
                    colorFrame.Width * colorFrame.BytesPerPixel     //stride
                    );
            }
        }
    }
}
แล้วลองรันโปรแกรมดูครับ น่าจะเห็นหน้าต่างแสดงผลภาพวิดีโอจาก Kinect แล้วล่ะครับ

เริ่มต้นกับ Kinect ด้วย C#

มี Kinect รุ่นแรกอยู่ในมือนานมากล่ะครับ ได้โอกาสเขียนโปรแกรมเล่นกับ Kinect แล้ว

สิ่งที่ต้องการ
1. KinectSDK ซึ่งถ้าใช้กับอุปกรณ์ Kinect รุ่นแรก ตัว SDK รุ่นล่าสุดจะเป็นรุ่น 1.8 ซึ่งดาวน์โหลดได้จาก http://www.microsoft.com/en-us/download/details.aspx?id=40278 จะได้ไฟล์ชื่อ KinectSDK-v1.8-Setup.exe มา ซึ่งใช้ได้กับทั้ง 32 และ 64 bits ครับ

2. Kinect for Windows Developer Toolkit (จะโหลดหรือไม่ก็ได้) ถ้าต้องการทดสอบ ดูตัวอย่างโค้ด ตัวอย่าง app สามารถดาวน์โหลดเพิ่มเติมได้ที่ http://go.microsoft.com/fwlink/?LinkID=323589 ในที่นี้ผมแนะนำให้โหลดครับ ก็จะได้ไฟล์ KinectDeveloperToolkit-v1.8.0-Setup.exe มา

3. Visual Studio สำหรับเขียนโปรแกรม ในที่นี้ผมได้ลองใช้ Visual Studio Express 2012 ซึ่งดาวน์โหลดได้ที่ http://www.microsoft.com/en-us/download/details.aspx?id=34673 มีตัว iso ให้ดาวน์โหลดเพื่อติดตั้งแบบ offline ครับ

ขั้นตอนการติดตั้ง
ว่าตามคำแนะนำของ Microsoft ในเว็บ http://www.microsoft.com/en-us/download/details.aspx?id=40278 เลยนะครับ
1. อย่าพึ่งต่อ Kinect เข้ากับคอม
2. ถ้าเคยติดตั้ง Kinect Driver แล้ว ลบออกให้หมดก่อน
3. ถ้าเคยติดตั้ง Microsoft Server Speech Platform ก็ลบออกให้หมดก่อน
4. ถ้าเคยติดตั้ง Kinect SDK แล้ว ไม่ต้องลบออกก็ได้ ลงตัวใหม่ก็จะไปอัพเดทให้ (ส่วนผมเองทำการลบออกไปก่อน)
5. ถ้าเปิด Visual studio อยู่ ให้ปิดไปก่อน
6. ติดตั้งไฟล์ KinectSDK-v1.8-Setup.exe
7. (ไม่บังคับ) ติดตั้ง KinectDeveloperToolkit-v1.8.0-Setup.exe
8. เสียบไฟ Kinect และเสียบเข้ากับพอร์ต USB ตัว driver จะถูกติดตั้งโดยอัตโนมัติ
9.  ตอนนี้ไฟที่ Kinect ก็จะติดเป็นสีเขียว

การทดสอบว่า Kinect ใช้งานได้
ถ้าติดตั้ง KinectDeveloperToolkit-v1.8.0-Setup.exe แล้ว ให้ไปที่ Start / Program / Kinect for Windows SDK 1.8 แล้วเลือก Developer Toolkit Browser

จากนั้นเลือกหัวข้อง Tools แล้วเลือก Run ของ Kinect Explorer-WPF ตามรูป

จะเห็นภาพจากกล้อง Kinect ครับ

ต่อไปเราจะลองเขียนโปรแกรมด้วย C# เพื่อเชื่อมต่อกับ Kinect กันครับ ดังนั้น จำเป็นต้องติดตั้ง Visual Studio Express 2012 ที่ดาวน์โหลดมา ก็ติดตั้งให้เรียบร้อยซึ่งใช้เวลานานพอสมควรครับ

หากสนใจหาหนังสือเกี่ยวกับ Kinect อ่าน ผมแนะนำเล่มนี้ครับ เขียนละเอียด เข้าใจง่ายดี

Start Here! Learn the Kinect API 
https://www.microsoft.com/learning/en-us/book.aspx?id=15815&locale=en-us

พบกันตอนต่อไปครับ

Friday, April 10, 2015

การแก้ปัญหาไม่สามารถเรียกใช้งาน Genymotion ได้

วันนี้เจอปัญหาว่าทำไมเครื่องคอมบางเครื่องก็รัน Genymotion ได้ แต่บางเครื่องไม่ได้ เครื่องที่เป็น Windows 8 ใช้งานได้ แต่พอมาใช้ Windows 7 ใช้ไม่ได้ซะงั้น ลองดูแต่ละปัญหาและวิธีแก้ไขกันครับ

ปัญหา Cannot create OVA
อันนี้เป็นปัญหาแรกๆเลย คือ ไม่สามารถสร้าง virtual device จาก ova ไฟล์ได้ วิธีแก้ไขคือให้ลองไปลบไฟล์ deployed ที่อาจจะเคยมีการสร้าง device ไว้ก่อนแล้วแต่ไม่สำเร็จ ซึ่งจะอยู่ที่ C:\Users\xxx\AppData\Local\Genymobile\Genymotion\deployed (ต้องกำหนดให้ show hidden files ก่อนจึงจะเห็นโฟลเดอร์นี้) ให้ลบทุกอย่างในโฟลเดอร์ deployed นี้แล้วลองสร้าง device ใหม่ครับ

ปัญหา Genymotion cannot start virtual device
วิธีตรวจสอบ ไปเปิด Virtualbox แล้วลองรัน device เอง ถ้ารันไม่ได้ แสดงว่าเป็นที่ Virtualbox ในที่นี้ผมได้ลองสองวิธีคือ
1. รัน Virtualbox แยกต่างหาก แล้วเลือกเมนู File/ Preferences/ Network เลือกแท็บ Host-only networks แล้วลบรายการ Adapter ที่มีอยู่ทั้งหมดออก จากนั้นค่อยรัน Genymotion ใหม่ ซึ่งมันจะมาสร้าง Adapter ที่นี่ใหม่ให้เอง
ถ้าไม่สำเร็จ อาจจะต้อง
2. downgrade Virtualbox ซึ่งผมได้ลองใช้เวอร์ชัน 4.3.12 แล้วใช้งานได้ครับ

ปัญหาที่ player.exe has stopped working
หลังจาก Virtualbox ทำงานแล้ว Genymotion ดันแครชแล้วแสดงข้อความข้างต้นแทน เท่าที่ค้นหาดูแล้วพบว่าเป็นเพราะ driver การ์ดจอไม่อัพเดท ประกอบกับเครื่องที่ใช้มีการ์ดจอสองแบบที่สลับใช้งานกันได้ เลยลองสลับเป็นการ์ดจออีกตัวนึง ก็ใช้งานได้เลย แต่ถ้าต้องการใช้การ์ดจอตัวแรกที่มีปัญหา ก็คงต้องไปอัพเดท driver มันใหม่ครับ ยืนยันว่าลองไปอัพเดทไดร์เวอร์การ์ดจอใหม่แล้ว ปัญหานี้ก็หายไปครับ

Friday, April 3, 2015

Microsoft Word กับการทำ บทที่ เลขหัวข้อ รูปที่ ตารางที่

ชื่อหัวข้อวันนี้เหมือนค่อนข้างยาว แต่มันตรงประเด็นเลยครับ คือทุกทีเวลาเราใช้ word ทำเอกสารที่เป็นรูปเล่ม มันก็ต้องมีตัวเลขของบท ของหัวข้อ รูป ตาราง ฯลฯ ซึ่งปกติ (มั้ง) เราก็จะพิมพ์กันเอง จัดรูปแบบกันเอง เพราะมันดูง่ายสุด แต่.....มันต้องทำทุกอัน ทุกเลข และยังไม่พอ ตอนไปทำสารบัญ สารบัญตาราง+รูป ต้องมาใส่เลขเอง ถ้าหน้าเลื่อน ก็ต้องกลับไปแก้เลขอีก หรือถ้าลบรูปหนึ่งรูป ก็ต้องกลับไปเรียงลำดับเลขรูปใหม่ทั้งในเนื้อหาและสารบัญ

มาดูกันครับ ว่าเราจะทำให้ปัญหาต่างๆเหล่านี้ คลี่คลายไปด้วยวิธีใด

สมมติว่าเรามีโครงสร้างแบบ บทที่ ซึ่ง word ไม่มีมาให้ เราก็ต้องสร้างเองครับ โดยมีขั้นตอนดังนี้
1. สร้าง Multi-level list ใหม่ โดยเลือกเมนูตามรูปครับ

2. จะได้หน้าต่างสำหรับกำหนดค่าขึ้นมา คลิกเลือกปุ่ม More ที่อยู่ด้านล่างซ้ายด้วยครับ

3. ปรับแก้รายละเอียดของ list นี้ในระดับ 1 ให้เป็นบทที่ ตามรูปครับ

4. เมื่อคลิก OK ก็จะเกิดข้อความ "บทที่ 1" ในเอกสาร ตอนนี้เราก็ได้โครงสร้างของบทที่แล้ว ต่อไปเราจะทำให้รูปแบบการแสดงผลเป็นไปอย่างที่เราต้องการ
5. ทำการปรับแก้ Style ของ "บทที่" โดยคลิกขวาที่แถบเมนู Style หัวข้อ "บทที่ 1" (ซึ่งก็คือ Heading 1) ตามรูป

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

7. ถึงขั้นตอนนี้ก็จะได้ข้อความ "บทที่ 1" อยู่กลางหน้าจออย่างที่ต้องการ
8. ต่อไปเราลองพิมพ์ชื่อบทเข้าไปด้วย เช่น บทที่ 1 บทนำ ตรงนี้ผมอยากให้คำว่า "บทนำ" ลงไปอยู่อีกบรรทัดนึง มันจะมีกระบวนการที่สำคัญคือ เราไม่สามารถเคาะ Enter ได้โดยตรง เพราะถ้าทำอย่างนั้นแล้วตอนใส่เลขรูป หรือ ตาราง จะเกิดปัญหาได้ (ไม่รู้ว่าเพราะอะไรเหมือนกันนะครับ) เลยต้องกด Shift+Enter ก่อนคำว่า "บทนำ" ให้มันขึ้นบรรทัดใหม่ แต่ยังอยู่ในย่อหน้า (paragraph) เดียวกับคำว่า "บทที่ 1" ก็จะได้ผลดังนี้

9. ต่อไปเราก็จะกำหนดค่าหัวข้อแรก คือ 1.1 โดยจะกำหนดให้เป็น style Heading 2 ดังนี้
9.1 คลิกขวาที่คำว่า บทที่ 1 แล้วเลือก Adjust list indents
9.2 ในส่วน Click level to modify ให้เลือกค่า 2
9.3 เพื่อไม่ให้สับสน แก้ไขส่วนของ Number format ก่อนให้เป็นดังรูป

9.4 จากนั้นเลือก Include level number from: แล้วเลือก Level 1 จะได้ผลดังรูป
9.5 ในช่องที่มีเลข 1 อยู่ ให้พิมพ์ . (จุด) และ เลือกหัวข้อ Number style for  this level: ตามรูป
9.6 กำหนดค่าที่เหลือตามรูป

9.7 คลิกขวาที่ Style / Heading 2 แล้วเลือก Modify

9.8 แก้ไขดังตัวอย่างในรูป

9.9 พิมพ์ข้อความที่ต้องการลงไป แล้วเลือก Style ให้เป็น Heading 2 จะได้ผลดังรูป

หากตัวเลข 1.1 ไม่แสดง ให้คลิกที่ข้อความ จากนั้นเลือกเมนูดังรูป


10. หากมี level ที่ต่ำลงไปอีกเช่น 1.1.1 ก็ให้ทำเหมือนกับข้อ 9.1-9.9 แต่เลือก level 3 เป็นต้น
11. ส่วนที่เป็น Style ที่ใช้เป็นตัวปกติคือ Normal ก็สามารถกำหนดค่าให้ชนิดและขนาดของฟอนต์เป็นไปตามต้องการได้ ทุกครั้งที่มีการสร้างหัวข้อหรือพิมพ์ข้อความ พยายามใช้ Style เป็นตัวกำหนดแทนการแก้ไขทีละส่วนเอง
12. หากต้องการเพิ่มชื่อรูป เมื่อใส่รูปแล้ว ให้เลือกเมนูตามรูป

13. ถ้าในหัวข้อ Options: Label เมื่อคลิกดูแล้วยังไม่มีคำว่า "รูปที่" ตามต้องการ ให้เลือก New Label: แล้วพิมพ์คำว่า "รูปที่" ลงไป

14. จากนั้นหากต้องการเลขของรูปเป็น รูปที่ 1.1 โดยที่เลขตัวแรกเป็นชื่อบท ก็ให้เลือก Numbering แล้วกำหนดค่าต่างๆตามรูป

ก็จะเกิดคำว่า รูปที่ 1.1

15. จากนั้นกำหนดค่า Style ของรูป ซึ่งจะเป็น Style ชื่อว่า Caption ให้เป็นไปตามต้องการ


ผลลัพธ์ก็จะได้ประมาณนี้ครับ

16. หากมีตารางก็ทำเหมือนกับรูป

17. สามารถแทรกสารบัญ สารบัญตาราง สารบัญรูปได้