2.Tìm hiểu và sử dụng thư viện Kinect
Thư viện Kinect là thư viện do
Microsoft tạo ra để tạo môi trường cho người dùng có thể dễ dàng xây dựng những
ứng dụng một cách nhanh chóng trên cả PC lẫn dòng máy chơi game Xbox 360. Thư
viện này hỗ trợ cho cả 3 ngôn ngữ thông dụng là C#, C++ và VB đồng thời cũng
tương thích với win7 và 8. Hiện tại, phiên bản mới nhất là SDK for Kinect version 1.6 đã cải tiến nhiều tính năng nên dễ sử dụng
và tỏ ra là một lựa chọn hiệu quả hơn so với các thư viện mã nguồn mở. Tuy
nhiên để sử dụng thư viện này cho các ứng dụng thương mại thì cần trả tiền bản
quyền cho Microsoft.
Yêu cầu hệ thống :
·
Visual Studio 2010 .
·
Kinect
Để bắt đầu với
tìm hiểu, ở đây sẽ sử dụng C#.
2.1 Tạo project:
Bước đầu tiên cần thực hiện là tạo một project mới, có thể là dạng
Windows Forms hay dạng WPF.
Bước tiếp theo là thực hiện add reference để có thể thao tác với
Kinect SDK. Bấm chuột phải vào phần References ở cửa sổ bên trái và chọn Add reference sau đó tìm file Microsoft.Kinect.dll trong tab .Net
Chú ý rằng nếu sử dụng các phiên bản beta thì file cần add là Microsoft.Research.Kinect.
2.2Thiết lập cho Kinect
Hầu như tất cả
các chương trình Kinect đều bắt đầu như nhau.
Đầu tiên là
tìm kiếm các senser đã kết nối với máy tính và kiểm tra tình trạng của chúng.
(Chú ý rằng các phiên bản trước thì code sẽ hơi khác so với bản 1.6)
Để
làm việc này chúng ta khai báo một đối tượng thuộc lớp KinectSenser
Khai báo thêm thư viện
kinect using Microsoft.Kinect;
Trong sự kiện WindowLoaded chúng
ta sử dụng lệnh foreach để kiểm tra tất cả các sensor đc kết nối.
foreach (var SensorKetNoi
in KinectSensor.KinectSensors)
{
if
(SensorKetNoi.Status == KinectStatus.Connected)
{
this.sensor
= SensorKetNoi;
break;
}
}
Khi tất cả các
senser đã được kết nối, ta tiến hành cho phép nhận các dòng dữ liệu cần thiết
cho ứng dụng như độ sâu, âm thanh hoặc ảnh màu từ cảm biến sau đó khởi động cảm
biến và viết các hàm để xử lý dữ liệu nhận được (Có thể là xuất ảnh ra màn
hình, tính toán khoảng cách, nhận dạng…)
if (null
!= this.sensor)
{
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
this.sensor.SkeletonStream.Enable();
// Khởi động
sensor!
}
2.3 Nhận và hiển thị dữ liệu từ cảm biến.
Dữ liệu gửi
về dưới dạng data stream. NUI API cho phép lập trình kiểm soát và truy nhập dữ
liệu.
Các bước làm bao gồm:
1.
Xác định dòng dữ liệu cần thiết.
2.
Cho phép mở dòng dữ liệu (Enable
Data Streaming)
3.
Tạo bộ đệm để lưu trữ dữ liệu sensor.
4.
Giải phóng bộ đệm để có thể sử dụng trong khung
hình tiếp theo.
Trong việc hiển thị dữ liệu, các hàm hỗ trợ trong SDK rất phức
tạp, các bạn có thể down Coding4Fun.Kinect.Toolkit về sau đó add reference đến
file coding4Fun.Kinect.winForm.dll
hoặc coding4Fun.Kinect hoặc coding.4Fun.kinect.Wpf.dll
(bằng cách chuột phải lên refeference -> chọn thẻ
browse-> dẫn đến thư mục Coding4Fun.Kinect.Toolkit)
Khi sử dụng bạn chú ý
thêm using Coding4Fun.Kinect.WinForm;
2.3.1 ColorStream:
ColorStream có
nhiều độ phân giải và định dạng tùy thuộc vào các lựa chọn colorStream là RGB,
YUV hay Bayer.
SDK cung cấp một số tùy chọn cho phép tối
ưu hóa camera ứng với các tác động môi trường như:
-
Tăng giảm độ sáng
-
Thay đổi màu sắc, độ tương phản
Tất cả được hỗ trợ trong class
ColorCameraSetting.
Để hiển thị các thành phần dữ liệu
mầu sắc bằng C# chúng ta cần tiến hành các công việc sau:
-
Khởi tạo cảm biến để tạo dữ liệu màu (đã đề cập ở
trên)
-
Xử lý sự kiện và hiển thị lên Forms.
a.
Tạo sự kiện báo dữ liệu đã sẵn sàng:
if (this.sensor != null)
{
this.sensor.ColorFrameReady
+= this.SensorColorFrameReady;
}
b.
Xử lý sự kiện và hiển thị lên Forms.
Ví
dụ bên dưới được thực hiện với windows Forms với sự hỗ trợ của công cụ Coding4Fun.Kinect.Toolkit . Để hiển thị với WPF các bạn
có thể tham khảo thêm ở địa chỉ.
private void SensorColorFrameReady(object
sender,
ColorImageFrameReadyEventArgs
e)
{
using
(ColorImageFrame colorFrame =
e.OpenColorImageFrame())
{
if
(colorFrame != null)
{
colorImage.Image =
colorFrame.ToBitmap();
}
}
}
2.3.2 Depth Stream
Mỗi khung hình của
dữ liệu Depth Stream được tạo thành từ các pixels chứa khoảng cách (bằng mm) từ
mặt phẳng camera đến đối tượng.
Các ứng dụng có thể sử dụng depth data để
bám theo chuyển động hoặc nhận dạng đối tượng.
Dữ
liệu về khoảng cách tính bằng mm là bộ số (x,y) chứa tọa độ trong field of view
của sensor.
Có 3
tùy chọn độ phân giải là 640x480 (mặc định), 320x240 vào 80x60. Tất cả được quy
định trong DepthImageFormat
Enumeration.
Việc
hiển thị dữ liệu cho DepthStream hoàn toàn tương tự ColorStream.
if (this.sensor != null)
{
this.sensor.DepthFrameReady
+= this.SensorDepthFrameReady;
}
private void SensorDepthFrameReady
(object sender,
ColorImageFrameReadyEventArgs
e)
{
using
(DepthImageFrame DepthFrame =
e.OpenColorImageFrame())
{
if
(DepthFrame != null)
{
DepthImage.Image = DepthFrame.ToBitmap();
}
}
}
2.4 Điều khiển góc nghiêng sensor
Góc nghiêng
của sensor trong kinect có giá trị từ -27 đến 27, giá trị này tính theo phương
vuông góc với trọng lực, tức là nếu góc bằng 0 thì phương của camera sẽ vuông
góc với trọng lực.
Để điều khiển góc nghiên của sensor ta sử dụng thuộc tính sensor.ElevationAngle
Thuộc tính này cho phép ta có thể get hoặc set giá trị cho
góc sensor.
Ví dụ sau mô tả việc hiển thị góc và đặt giá trị góc nghiêng
bằng một thanh cuộn ngang kết hợp với 1 nút bấm và hiển thị giá trị đó lên một
label.
private void
hScr_dieuChinhGoc_ValueChanged(object sender, EventArgs e)
{
lbl_gocnghieng.Text = hScr_dieuChinhGoc.Value.ToString();
}
private void
button1_Click(object sender, EventArgs e)
{
sensor.ElevationAngle = hScr_dieuChinhGoc.Value;
}
2.5 Demo sử dụng Kinect với WindowsForms
Demo này tổng hợp lại các ví dụ ở trên trong đó sử dụng các
thành phần sau:
-
2 PictureBox là colorImage và DepthImage để hiển
thị dữ liệu ảnh mầu và dữ liệu độ sâu.
-
1 HscrollBar là hScr_dieuChinhGoc kết hợp với 1
Button để đặt giá trị góc quay.
-
Các lable lbl_HienThiGocNghieng và
lbl_gocnghieng để hiển thị giá trị đo góc.
v
Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Kinect;
using Coding4Fun.Kinect.WinForm;
namespace DemoWinForm2
{
public partial class Form1 : Form
{
private KinectSensor
sensor;// Khai báo sensor
public Form1()
{
InitializeComponent();
}
private void
Form1_Load(object sender, EventArgs e)
{
//Kiểm tra các sensor được kết nối
foreach(var
sensorKetnoi in KinectSensor.KinectSensors)
{
if(sensorKetnoi.Status==KinectStatus.Connected)
{
this.sensor
= sensorKetnoi;
break;
}
}
if(this.sensor!=null)
{
// Enable dòng dữ liệu và thiết lập các tùy chọn cho dữ liệu
ảnh
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// Enable dòng dữ liệu và thiết lập các
tùy chọn cho dữ liệu độ sâu
this.sensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
// Khởi động sensor
this.sensor.Start();
// Hiển thị góc nghiêng ban đầu của sensor.
lbl_gocnghieng.Text = sensor.ElevationAngle.ToString();
// Các sự kiện thông báo dữ liệu đã sẵn sàng.
this.sensor.ColorFrameReady += this.SensorColorFrameReady;
this.sensor.DepthFrameReady += this.SensorDepthFrameReady;
}
}
// Xử lý các sự kiện.
private void
SensorColorFrameReady(object sender,
ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame
colorFrame = e.OpenColorImageFrame())
{
if (colorFrame != null)
{
colorImage.Image = colorFrame.ToBitmap();
}
}
}
private void
SensorDepthFrameReady(object sender,
DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame
depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame != null)
{
depthImage.Image= depthFrame.ToBitmap();
}
}
}
private void
Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (sensor != null)
{
// Đưa góc nghiêng về 0 trước khi tắt sensor.
sensor.ElevationAngle = 0;
sensor.Stop();
}
}
// Các hàm xử lý sự kiện để điều chỉnh góc nghiêng.
private void
hScr_dieuChinhGoc_ValueChanged(object sender, EventArgs e)
{
lbl_gocnghieng.Text = hScr_dieuChinhGoc.Value.ToString();
}
private void
button1_Click(object sender, EventArgs e)
{
sensor.ElevationAngle = hScr_dieuChinhGoc.Value;
}
}
}
v
Kết quả:
Trên đây là những tìm hiểu mang tính chất tổng hợp kiến thức, tuy rằng vẫn đang còn sơ lược nhưng có thể sẽ hữu ích với những bạn mới bắt đầu tiếp cận với Kinect.