如何使用Kinect_V2_在WPF開發應用_基於KinectV2開發的_揮拍復健系統測試_加油~體感復健系統開發工程師
首先我們應該要先能夠開啟Kinect 攝像機
Kinect 的 準備流程
(1) 取得 Sensor / Get the sensor
(2)選擇你所要讀取的資料源(data source) / Select the data source to read from
(3)處理從資料源讀取到的資料 / Handle the data you read from the source
從「傳感器」獲得「源」
從「源」打開「閱讀器」
【第一階段_先開啟彩色視訊】
MainWindow.xaml.cs
(程式運行的功能)
MainWindow.xaml
(介面布局)
效果圖
可以開啟彩色視訊畫面了
緊接著
我做了幾件事情
KinectV2 _ 雙手y座標值顯示 開發平台 WPF
藉助於 WPF 幫助我們 秀出 y座標值的改變
可以清楚觀察到 兩手 y座標值上升下降隨之改變
我們在來做一件事情
將 y座標值改為
z座標值
【KinectV2雙手Z座標值變化觀察】
目的 觀察手部離攝影機的遠近變化幅度
擬研究出一套簡易的揮拍計數系統
左下方 textBox 藉助於 WPF 幫助我們 秀出 揮拍計數
本來是想試著統計揮拍次數
後來問了資深高手和老師發線
Accelerator 在舊版kinect裡才有,新版因無需求,而沒在裡面
末位置、初位置,就是位置而已,拿位置來用即可
這裡我做了一個簡易版的計算
MainWindow.xaml.cs
(程式運行的功能)
MainWindow.xaml
(介面布局)
會有這個衝動做這個 除了一個原因是因為專題需用到之外
還有就是是 看到 朋友
Vangos 做了一個舉重的應用
覺得很厲害
也想像他學習
XDD 加油 體感復健系統開發工程師
Kinect 的 準備流程
(1) 取得 Sensor / Get the sensor
(2)選擇你所要讀取的資料源(data source) / Select the data source to read from
(3)處理從資料源讀取到的資料 / Handle the data you read from the source
從「傳感器」獲得「源」
從「源」打開「閱讀器」
【第一階段_先開啟彩色視訊】
MainWindow.xaml.cs
(程式運行的功能)
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 Kinect_V2_flappy_bird
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
KinectSensor sensor;
ColorFrameReader colorFrameReader;
WriteableBitmap colorBitmap;
public MainWindow()
{
InitializeComponent();
//Get the sensor
sensor = KinectSensor.GetDefault();
sensor.Open();
//setup readers for each source of data we want to use
colorFrameReader = sensor.ColorFrameSource.OpenReader();
//setup event handlers that use what we get from the readers
colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;
//create the bitmap to display
colorBitmap = new WriteableBitmap(1920,1080,96.0,96.0,PixelFormats.Bgr32,null);
ColorImage.Source = colorBitmap;
}
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
//Get the current frame in a memory-safe manner
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
//Defensive programming : Just in case the sensor frame is no longer valid
if (colorFrame == null)
return;
using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer() )
{
//Put a thread-safe lock on this data so it doesn't get modified elsewhere
colorBitmap.Lock();
//Let the application know where the image is being stored
colorFrame.CopyConvertedFrameDataToIntPtr(
colorBitmap.BackBuffer,
(uint)( 1920 * 1080 * 4 ), //width*height*BytesPerPixel
ColorImageFormat.Bgra);
//Let the application know that it needs to redraw the screen in this area(the whole image)
colorBitmap.AddDirtyRect(new Int32Rect(0,0,colorBitmap.PixelWidth,colorBitmap.PixelHeight));
//Remove the thread-safe lock on this data
colorBitmap.Unlock();
}
}
}
void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
sensor.Close();
}
}
}
MainWindow.xaml
(介面布局)
<Window x:Class="Kinect_V2_flappy_bird.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">
<Grid>
<Image x:Name="ColorImage" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="UniformToFill"/>
</Grid>
</Window>
效果圖
可以開啟彩色視訊畫面了
緊接著
我做了幾件事情
KinectV2 _ 雙手y座標值顯示 開發平台 WPF
藉助於 WPF 幫助我們 秀出 y座標值的改變
可以清楚觀察到 兩手 y座標值上升下降隨之改變
我們在來做一件事情
將 y座標值改為
z座標值
【KinectV2雙手Z座標值變化觀察】
目的 觀察手部離攝影機的遠近變化幅度
擬研究出一套簡易的揮拍計數系統
左下方 textBox 藉助於 WPF 幫助我們 秀出 揮拍計數
本來是想試著統計揮拍次數
後來問了資深高手和老師發線
Accelerator 在舊版kinect裡才有,新版因無需求,而沒在裡面
末位置、初位置,就是位置而已,拿位置來用即可
這裡我做了一個簡易版的計算
雙手一同靠近攝影機鏡頭時
值約介於 0.6160924 ~ 0.6857489
雙手一同遠離攝影機鏡頭時
值約介於1.534026 ~ 1.82197
右手Z值
第一次遠離為
為 1.821213
第一次靠近
為 0.6228145
第二次遠離
為 1.836249
第二次靠近
為 0.6664682
第三次遠離
為 1.853669
第三次靠近
為 0.6488236
我們把 第一次靠近值相加取平均
( 0.6228145 + 0.6664682 + 0.6488236 ) / 3 = 0.6460354333
再把 第一次遠離值相加取平均
( 1.821213 + 1.836249 + 1.853669 ) / 3 = 1.83704366
這樣就可以得到兩組平均門檻值
最後將 這兩個得到的平均值相加
除以2
(0.6460354333 + 1.83704366 ) / 2 = 1.24153954665
這個數值我們稱之為「中間值平面」
Median Value Plane
這個數值先暫存起來等之後或許會有用到
基於KinectV2開發的_揮拍復健系統測試(右撇子)測試
-網球肘,顧名思義是網球運動常發生的症狀,一般而言,大約有30%的網球選手都有過這樣的經驗,其實網球肘不止是網球的專利,像是高爾夫球、棒球、排球等需要做出擊球、投球動作的運動上、都能見到網球肘的蹤跡,只要感覺肘關節周圍有出現原因不明的疼痛,就可泛稱為網球肘。
MainWindow.xaml.cs
(程式運行的功能)
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 Kinect_V2_flappy_bird
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
KinectSensor sensor;
ColorFrameReader colorFrameReader;
BodyFrameReader bodyFrameReader;
WriteableBitmap colorBitmap;
Body[] bodies;
public MainWindow()
{
InitializeComponent();
//Get the sensor
sensor = KinectSensor.GetDefault();
sensor.Open();
//setup readers for each source of data we want to use
colorFrameReader = sensor.ColorFrameSource.OpenReader();
bodyFrameReader = sensor.BodyFrameSource.OpenReader();
//setup event handlers that use what we get from the readers
colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;
bodyFrameReader.FrameArrived += this.Reader_BodyFrameArrived;
//create the bitmap to display
colorBitmap = new WriteableBitmap(1920,1080,96.0,96.0,PixelFormats.Bgr32,null);
ColorImage.Source = colorBitmap;
}
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame == null)
return;
if (bodies == null)
{ //Create an array of the bodies in the scene and update it
bodies = new Body[bodyFrame.BodyCount];
}
bodyFrame.GetAndRefreshBodyData(bodies);
//For each body in the scene
foreach (Body body in bodies)
{
if (body.IsTracked)
{
var joints = body.Joints; // Get all of the joints in that body
if(joints[JointType.HandRight].TrackingState==TrackingState.Tracked &&
joints[JointType.HandLeft].TrackingState == TrackingState.Tracked)
{
//txtLeft.Text = joints[JointType.HandLeft].Position.Y.ToString();
//txtRight.Text = joints[JointType.HandRight].Position.Y.ToString();
txtLeft.Text = joints[JointType.HandLeft].Position.Z.ToString();
txtRight.Text = joints[JointType.HandRight].Position.Z.ToString();
if (joints[JointType.HandRight].Position.Z < 0.6460354333)
{
avgNear.Content = "靠近了";
}
else
{
avgNear.Content = "沒靠近了";
}
if (joints[JointType.HandRight].Position.Z > 1.83704366)
{
avgFar.Content = "遠離了";
}
else
{
avgFar.Content = "沒遠離了";
}
}
}
}
}
}
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
//Get the current frame in a memory-safe manner
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
//Defensive programming : Just in case the sensor frame is no longer valid
if (colorFrame == null)
return;
using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer() )
{
//Put a thread-safe lock on this data so it doesn't get modified elsewhere
colorBitmap.Lock();
//Let the application know where the image is being stored
colorFrame.CopyConvertedFrameDataToIntPtr(
colorBitmap.BackBuffer,
(uint)( 1920 * 1080 * 4 ), //width*height*BytesPerPixel
ColorImageFormat.Bgra);
//Let the application know that it needs to redraw the screen in this area(the whole image)
colorBitmap.AddDirtyRect(new Int32Rect(0,0,colorBitmap.PixelWidth,colorBitmap.PixelHeight));
//Remove the thread-safe lock on this data
colorBitmap.Unlock();
}
}
}
void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
sensor.Close();
}
}
}
MainWindow.xaml
(介面布局)
<Window x:Class="Kinect_V2_flappy_bird.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800">
<Grid>
<Image x:Name="ColorImage" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="UniformToFill"/>
<TextBox x:Name="txtLeft" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" FontSize="18.667"/>
<TextBox x:Name="txtRight" HorizontalAlignment="Right" Height="23" Margin="0,0,-0.333,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" FontSize ="18.667"/>
<TextBox x:Name="txtNum" HorizontalAlignment="Left" Height="23" Width="120" VerticalAlignment="Bottom" FontSize="18.667" TextWrapping="Wrap"/>
<Label x:Name="avgNear" Content="接近靠近平均值時做警示" HorizontalAlignment="Left" Margin="547,498,0,0" VerticalAlignment="Top" Height="48" Width="235" FontSize="18.667" Background="#FF1B9EC5" Foreground="#FF782064" />
<Label x:Name="avgFar" Content="接近遠離平均值時做警示" HorizontalAlignment="Left" Margin="547,445,0,0" VerticalAlignment="Top" Height="48" Width="235" FontSize="18.667" Background="#FF62B84F" BorderBrush="#FFDADA3F" Foreground="#FF020295" />
</Grid>
</Window>
會有這個衝動做這個 除了一個原因是因為專題需用到之外
還有就是是 看到 朋友
Vangos 做了一個舉重的應用
覺得很厲害
也想像他學習
XDD 加油 體感復健系統開發工程師
留言
張貼留言