السلام عليكم و رحمة الله
البداية مع جهاز الـ Kinect
مقدمة
اذا كنت لم تسمع مسبقا بهذا الجهاز – المقدم من شركة ميكروسوفت – يمكنك ببساطة زيارة صفحة الويكيبيديا للتعرف على هذا الجهاز الرائع!
http://en.wikipedia.org/wiki/Kinect
ببساطة جدا يمكن اعتبار الجهاز ككاميرا. يسمح لنا الجهاز بأدخال video & audio. الجديد في الجهاز والذي يمكن اعتباره نقله في التعامل مع الصور خاصة، ان الجهاز يتعامل مع depth image. يعني يمكن ان تعرف بعد object معين عن جهاز الـ Kinect. طبعا هذا الامر يسهل كثير من الامور التي تخص التعامل مع الصور. لذا رغم اطلاق هذا الجهاز في اول الامر لجهاز الـ Xbox الا انه أسال لعاب المبرمجين و الباحثين لأستخدام هذا الجهاز في مجالات عديدة بعيدة عن الالعاب مثلا يمكن استخدام الجهاز في تطبيقات تخص
HealthcareRoboticsEducationVirtual realityMilitary
بصراحة انا قبل اشهر فقط تعرفت على هذا الجهاز وقررت ان احصل على واحد وابدء بتعلم اسرار البرمجة الخاصة به. طبعا الجهاز اطلق في بادء الامر لأجهزة الـ Xbox ثم بعد ذلك اطلقت مايكروسوفت نسخة خاصة بالوندوز. انت يمكنك البدء بالبرمجة سواءا على نسخة الـ Xbox او النسخة الخاصة بـ windows. الفرق الوحيد الذي اعرفه لحد الان هو ان نسخة الويندوز تكون افضل و ادق في كشف و تتبع الاجسام القريبة من جهاز الـ Kinect. النسخة الخاصة بـ Xbox تفشل في تتبع الاجسام الاقرب من 80 cm بينما نسخة الويندوز تعمل حتى حدود الـ 40 cm.
متطلبات العمل:
Windows 7 or 8
Visual Studio 2010 or 2012
Kinect for Windows SDK
والتي يمكن تحميلها من هنا
http://www.microsoft.com/en-us/kinectforwindows/develop/developer-downloads.aspx
Kinect device (for Xbox or Windows)
http://www.amazon.com/Microsoft-Xbox-Kinect-Sensor-360/dp/B009XD5YV0/ref=pd_sim_vg_1
http://www.amazon.com/Microsoft-L6M-00001-Kinect-for-Windows/dp/B006UIS53K
Power Supply Cable for Kinect
http://www.amazon.com/gp/product/B004S7GA46/ref=oh_details_o04_s00_i00?ie=UTF8&psc=1
الجهاز الذي لدي انا هو الخاص بالـ Xbox.
ملاحظة: هناك عدة مكتبات لكتابة تطبيقات خاصة بجهاز Kinect وربما من اشهرها OpenNi
لكن في هذه المقدمة، سأستخدم المكتبة الخاصة بميكروسوفت لأني اجيد لغة الـ C# والتي ستسهل على العمل. (احاول الان التعامل مع الـ OpenNI وربما يكون درس لي خاص به في المستقبل بمشيئة الله)
عملية اعداد (تنصيب) الحزمة الخاصة بمايكروسوفت سهلة جدا – فقط ملاحظة انه يجب عند تنصيب الحزمة يكون جهاز الـ Kinect غير متصل بجهاز الحاسب. بعد انتهاء عملية التنصيب يمكنك وصل الجهاز للبدء بكتابة التطبيقات الخاصة بالـ Kinect.
الان وبعد تنصيب الحزمة الخاصة بالـ Kinect وربط الجهاز ، يمكنك كتابة تطبيقك الاول.
كون مشروع جديد من نوع WPF
من نافذة الـ Solution Explorer قم بالضغط على Reference بالزر الايمن واختار Add Reference
من النافذة التي تظهر اختر جزء Browse واذهب الى مكان تنصيب Kinect sdk على جهاز الحاسب والذي من المفترض ان يكون
C:\Program Files\Microsoft SDKs\Kinect\v1.6\Assemblies\
ثم اختر ملف Microsoft.Kinect.dll
الان اول شيء يجب عمله في الجزء الخاص بالكود هو اضافة جملة الـ using الخاصة بمكتبة الـ Kinect
Using Microsoft.Kinect;
الان، للتعامل مع Kinect تحتاج الى تعريف object من KinectSensor class
قم بأضافة هذا التعريف كما موضح في الصورة
سنقوم بالتهيئة والتعامل مع هذا الـ object داخل الحدث Loaded الخاص بالبرنامج، لذا سنقوم الان بأضافة الحدث Loaded الى برنامجنا، ولعمل ذلك انتقل الى الجزء الخاص بالتصميم في برنامج الفيجوال استوديو. تأكد من ان الاختيار والجزء المفعل من برنامجك هو window ثم من الجزء الخاص بالاحداث (events) اضغط double click على الحدث Loaded
ستنتقل تلقائيا الى ملف الكود حيث سنضيف بعض الكود داخل هذا الحدث.
اولا سنقوم بتهيئة المتغير myKinect ( والذي سبق وان عرفناه ) بأضافة هذا السطر
myKinect = KinectSensor.KinectSensors[0];
طبعا هنا ال KinectSensors عبارة عن collection يقوم بخزن جميع الـ Kinect devices المتصلة مع الجهاز. انا لدي فقط جهاز Kinect واحد والذي سيكون رقمه [0] . يعني لو كان لديك اكثر من جهاز Kinect يمكنك التعامل مع كل واحد بصورة مستقلة.
الان انا متصل مع جهاز الـ Kinect برمجيا ويمكنني البدء بالتعامل فعليا معه.
بما انه جهاز الـ Kinect يمكنني من الحصول عن البيانات في وضعيات مختلفة (حيث ممكن استخدامه ككاميرا اعتيادية او استخدامه للحصول على depth image او حتى audio)، لذا اول خطوة يجب ان تكون هي تحديد مانوع البيانات او طريقة الحصول على البيانات من جهاز الـ Kinect. في هذا التطبيق سنستخدم الجهاز ككاميرا اعتيادية – اي الحصول على color video. لنعمل ذلك سنضيف
myKinect.ColorStream.Enable();
هنا دالة Enable استخدمناها بصورتها الاساسية دون اي متغيرات لذا هذه الدالة ستقوم بتوليد video frames بأبعاد 640 X 480 بمعدل 30 frames كل ثانية.
الان اخبرنا الـ Kinect بأننا نريد الحصول على البيانات من ما يعرف بـ RGB Camera (اي الكاميرا العادية). الخطة التالية ستكون هي اخبار برنامجنا ماذا سيفعل عند الحصول على الصور من الكاميرا. طبعا الفيجوال ستوديو يوفر لنا حدث (event) لهذا الامر.
الحدث هو ColorFrameReady والذي يتولد كلما يكون هناك frame جديد من الـ kinect
قم بأضافة
myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);
طبعا الفيجوال ستوديو يساعدك كثير في كتابة الكود. يعني في الكود الذي في الاعلى بمجرد ان تكتب = وتضغط space سترى كما في الصورة
كل ما عليك هو ان تضغط tab ثم سيقترح عليك مرة اخرى الفيجوال ستوديو بتعريف الدالة لك ايضا اضعط tab
ستكون الدالة كالاتي
void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
throw new NotImplementedException();
}
الان ببساطة الذي حدث انه اخبرنا برنامجنا انه كلما يأتيه frame جديد يقوم بأستدعاء دالة myKinect_ColorFrameReady
وطبعا سنقوم بعد قليل بكتابة الكود الخاص بهذه الدالة.
اخيرا ما سنحتاجه هنا هو استدعاء دالة Start لتقوم فعليا ببدء جهاز الـ Kinect .
سيصبح الكود الكلي الخاص بـ Loaded هو كالتالي
private void Window_Loaded(object sender, RoutedEventArgs e)
{
myKinect = KinectSensor.KinectSensors[0];
myKinect.ColorStream.Enable();
myKinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(myKinect_ColorFrameReady);
myKinect.Start();
}
الان سننتقل الى جزء اخر من البرنامج وهو التعامل مع البيانات المستلمة. سنقوم بعرض هذه الصور (frames) في برنامجنا. اولا سنحتاج الى ان نضيف الى واجهة برنامجنا ما يعرف بـ image element (هذا الجزء يخص الـ WPF ولغة الـ XAML) عموما الامر بسيط حتى اذا كنت لا تجيد التعامل جيدا مع الـ WPF (مثلي :D )
انتقل الى جزء التصميم – اي الى ملف MainWindow.xaml. يمكنك التعامل مع واجهة برنامجك من خلال كتابة كود xaml من خلال نافذة 1 في الصورة، او يمكنك اضافة الـ controls من خلال الـ Toolbox مباشرة الى نافذة 2.
سنقوم بأستخدام كود XAML وسنقوم بتعديل بسيط بحذف Grid واضافة Image حيث سيكون الكود الكلي الخاص بالنافذة كما موضح
<Window x:Class="KinectCam.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Image Name="kinectVideo" />
</Window>
الان بقي الجزء الاخير وهو كتابة الكود الخاص بالدالة myKinect_ColorFrameReady والتي ستقوم بعرض الـ frame على نافذة برنامجي.
الكود الكلي الخاص بالدالة سيكون كالتالي:
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, // resoultion - 96 dpi for video frames
PixelFormats.Bgr32, // video format
null, // platte - none
colorData, //video data
colorFrame.Width * colorFrame.BytesPerPixel); // stride
}
اولا في الكود السابق، يجب الحصول على الصورة والتي تمرر الى الدالة عن طريق المتغير e. وبما اننا مسبقا نعرف اننا نتعامل مع الـ RGB camera وسنحصل على صورة بالالوان، قمنا بتعريف متغيير من نوع ColorImageFrame لخزن الصورة به.
(طريقة تعريف المتغيير بهذه الطريقة – اي داخل جملة using – تكون اكثر كفاءة للتعامل مع الذاكرة خاصة في حالة برنامجنا حيث سيكون لدينا 30 frames في كل ثانية. بهذه الطريقة سنضمن انه يتم التخلص من المتغيير عندما تنتفي الحاجة اليه)
ثم بعد ذلك جملة
if (colorFrame == null)
return;
للتأكيد ان كل شيء على ما يرام واننا لسنا – لسبب او لاخر – فقدنا الاتصال او الصورة من الجهاز.
ثم في الخطوات التالية، قمنا بتعريف متغيير buffer لخزن الصورة. حجم هذا الـ buffer سيكون بحجم البايتات في الصورة والذي يمكن معرفته من خلال colorFrame.PixelDataLength.
اخيرا لعرض الصورة على kinectVideo (وهو الجزء الخاص بعرض الصورة الذي قمنا بأضافته في ملف الـ xmal) سنقوم بأستخدام خاصية Source واعطاءها القيمة المرجعة من دالة BitmapSource.Create
اخيرا قم بتنفيذ البرنامج لترى الفيديو من الكاميرا.
و السلام عليكم ورحمة الله

