Kinect V2 在Windows Form 上的配置教學_秀彩色影像_L1
Step1. 開啟 Windows Form 專案
介面部分先單純只拉一個pictureBox物件
Step2.引入Kinect v2 的參考 及 命名空間
Step3. 撰寫程式碼
這次目標要顯示彩影
首先我們要先思考怎麼秀出一般彩色影像
在一開始需要先宣告
【首先要引入(用)兩個命名空間(函式庫)】
一個是using Microsoft.Kinect
for Kinect SDK
一個是using System.Drawing.Imaging
用來指定 像素格式
起初需在一開始做三個東西的宣告(皆要引用Microsoft.Kinect)
private KinectSensor KsOpen = null;//啟動Kinect感測器(傳感器接口處理)
private FrameDescription frameDes = null;//影格描述
private ColorFrameReader colorReader ;//開啟
在Kinect SDK V2中的基本觀念
從「傳感器」獲得「源」
從「源」打開「閱讀器」
開啟Kinect V2彩色視訊三階段處理(傳感器-->源-->閱讀器)
傳感器 三步驟處理
1.a 傳感器接口處理
private KinectSensor KsOpen = null;//啟動Kinect感測器 ...........................1.a
1.b獲得傳感器的默認
KsOpen = KinectSensor.GetDefault();//Kinect v2感測器獲取(獲得傳感器的默認)............1.b
1.c打開傳感器
KsOpen.Open();//開啟Kinect 使用它......................................................1.c
切記!!!
1.b 和 1.c都在
Form1_Load時做
===================================================================
源 兩步驟處理
從傳感器得到源
2.a顏色源之frame接口處理(先宣告 源 之影像影格描述)
private FrameDescription frameDes = null;//影格描述(顏色源之frame接口)................2.a
使用 FrameDescription這個類(記得引用Microsoft.Kinect)
來做宣告
用來接收KinectSensor的彩色數據源
2.b獲得從傳感器接收到的彩色數據源
frameDes = KsOpen.ColorFrameSource.FrameDescription;
//獲得從傳感器接收到的彩色數據源.............2.b
===================================================================
閱讀器 兩步驟處理
從源打開閱讀器
3.a 彩屏閱讀器界面框架(宣告彩色閱讀器)
3.b從感測器接收到的彩色數據源中開啟彩色Reader
在 using System.Drawing.Imaging命名空間下
可滿足開發者指定像素格式的需求
後方有眾多PixelFormat這個列舉型態提供的像素格式參數
在此我們選用 PixelFormat.Format32bppRgb
用來秀RGB
使用WritableBitmap來做處理
這邊請教了 我的好朋友 Vangos 如何在Windows Form撰寫 V2
而不是在WPF
這裡我們需要用Bitmap來代替WriteableBitmap
Bitmap使用
(1)宣告
(2)指定參數(寬 , 高 , 像素格式 )
WriteableBitmap 類別
提供 BitmapSource ,可以寫入而更新。
命名空間: System.Windows.Media.Imaging
網頁link:
https://msdn.microsoft.com/zh-tw/library/system.windows.media.imaging.writeablebitmap(v=vs.110).aspx
Bitmap 類別
封裝 GDI+ 點陣圖的像素資料的圖形映像和其屬性所組成。
A Bitmap 是用來處理影像像素資料所定義的物件。
命名空間: System.Drawing
組件: System.Drawing (在 System.Drawing.dll 中)
網頁link:
https://msdn.microsoft.com/zh-tw/library/system.drawing.bitmap(v=vs.110).aspx
彩色數據流排放格式順序和大小
彩色圖像的結構
每一pixel佔32個位元,也就是4個byte
其中是以 藍 --> 綠 --> 紅 --> 透明值 這樣排序
皆為 unsigned integer
我們來想一下一整張frame 共包含多個 pixel 呢???
不是就 寬 乘 高 這麼多嗎
那每一 pixel 又佔了 4個byte
喔 原來如此
那就需要多宣告一個 unit 做大小吧!!!
你也可以用 UInt32 會有 異曲同工之妙
第一階段程式碼
不過你在測試完之後會發現有幾個問題需要修正
第一.影像畫面有點不穩定
第二.只顯示在某一區塊(右上角還左上角的樣子)
手靠近感測器 畫面
原因是因為
PictureBoxSizeMode.Normal:
默認情況下,在Normal 模式中,
Image 置於PictureBox 的左上角,
凡是因過大而不適合PictureBox 的任何圖像部分都將被剪裁掉
PictureBoxSizeMode這個列舉型態提供總共五種參數給你作修正
若沒設定 默認就為 Normal 喔!!!!
PictureBoxSizeMode.StretchImage:
使用StretchImage 值會使圖像拉伸或收縮,較適合PictureBox,方便我們看到完整畫面喔。
PictureBoxSizeMode.CenterImage:
使用CenterImage 值會使圖像居於工作區的中心。
PictureBoxSizeMode.Zoom:
使用Zoom 的值可以使圖像被拉伸或收縮以適應PictureBox;但是仍然保持原始寬高比。
PictureBoxSizeMode.AutoSize:
使用AutoSize 值會使控件調整大小,以便總是適合圖像的大小
在經過多次測試後
發現很長跳出此錯誤訊息
到底發生捨麼問題了 真是God!!!!
他是說需要多加一個 判別 colorFrame 是否為 null 的判斷
那我們就加吧
修正過後的
最後階段code
希望對相關開發者有幫助
------------------------------------------------------------------------------------------------------
PictureBoxSizeMode部分參考部落格
【C#圖解】PictureBox.SizeMode 屬性 作者:銀月術
http://blog.csdn.net/moonsilvering/article/details/5940506
Bitmap部分代換問題請教於
微軟MVP
Vangos Pterneas
介面部分先單純只拉一個pictureBox物件
Step2.引入Kinect v2 的參考 及 命名空間
Step3. 撰寫程式碼
這次目標要顯示彩影
首先我們要先思考怎麼秀出一般彩色影像
在一開始需要先宣告
【首先要引入(用)兩個命名空間(函式庫)】
一個是using Microsoft.Kinect
for Kinect SDK
一個是using System.Drawing.Imaging
用來指定 像素格式
起初需在一開始做三個東西的宣告(皆要引用Microsoft.Kinect)
private KinectSensor KsOpen = null;//啟動Kinect感測器(傳感器接口處理)
private FrameDescription frameDes = null;//影格描述
private ColorFrameReader colorReader ;//開啟
在Kinect SDK V2中的基本觀念
從「傳感器」獲得「源」
從「源」打開「閱讀器」
開啟Kinect V2彩色視訊三階段處理(傳感器-->源-->閱讀器)
傳感器 三步驟處理
1.a 傳感器接口處理
private KinectSensor KsOpen = null;//啟動Kinect感測器 ...........................1.a
1.b獲得傳感器的默認
KsOpen = KinectSensor.GetDefault();//Kinect v2感測器獲取(獲得傳感器的默認)............1.b
1.c打開傳感器
KsOpen.Open();//開啟Kinect 使用它......................................................1.c
切記!!!
1.b 和 1.c都在
Form1_Load時做
===================================================================
源 兩步驟處理
從傳感器得到源
2.a顏色源之frame接口處理(先宣告 源 之影像影格描述)
private FrameDescription frameDes = null;//影格描述(顏色源之frame接口)................2.a
使用 FrameDescription這個類(記得引用Microsoft.Kinect)
來做宣告
用來接收KinectSensor的彩色數據源
2.b獲得從傳感器接收到的彩色數據源
frameDes = KsOpen.ColorFrameSource.FrameDescription;
//獲得從傳感器接收到的彩色數據源.............2.b
===================================================================
閱讀器 兩步驟處理
從源打開閱讀器
3.a 彩屏閱讀器界面框架(宣告彩色閱讀器)
3.b從感測器接收到的彩色數據源中開啟彩色Reader
在 using System.Drawing.Imaging命名空間下
可滿足開發者指定像素格式的需求
後方有眾多PixelFormat這個列舉型態提供的像素格式參數
在此我們選用 PixelFormat.Format32bppRgb
用來秀RGB
使用WritableBitmap來做處理
這邊請教了 我的好朋友 Vangos 如何在Windows Form撰寫 V2
而不是在WPF
這裡我們需要用Bitmap來代替WriteableBitmap
Bitmap使用
(1)宣告
(2)指定參數(寬 , 高 , 像素格式 )
WriteableBitmap 類別
提供 BitmapSource ,可以寫入而更新。
命名空間: System.Windows.Media.Imaging
網頁link:
https://msdn.microsoft.com/zh-tw/library/system.windows.media.imaging.writeablebitmap(v=vs.110).aspx
Bitmap 類別
封裝 GDI+ 點陣圖的像素資料的圖形映像和其屬性所組成。
A Bitmap 是用來處理影像像素資料所定義的物件。
命名空間: System.Drawing
組件: System.Drawing (在 System.Drawing.dll 中)
網頁link:
https://msdn.microsoft.com/zh-tw/library/system.drawing.bitmap(v=vs.110).aspx
彩色數據流排放格式順序和大小
彩色圖像的結構
每一pixel佔32個位元,也就是4個byte
其中是以 藍 --> 綠 --> 紅 --> 透明值 這樣排序
皆為 unsigned integer
我們來想一下一整張frame 共包含多個 pixel 呢???
不是就 寬 乘 高 這麼多嗎
那每一 pixel 又佔了 4個byte
喔 原來如此
那就需要多宣告一個 unit 做大小吧!!!
你也可以用 UInt32 會有 異曲同工之妙
第一階段程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Kinect; // for Kinect SDK
using System.Drawing.Imaging; // for PixelFormat
namespace KinectV2_WindowsFormsApplication
{
public partial class Form1 : Form
{
private KinectSensor KsOpen = null;//啟動Kinect感測器
private FrameDescription frameDes = null;//影格描述
private ColorFrameReader colorReader ;
private Bitmap Bmp; // 給影像pictureBox物件做承載
private Rectangle Rect;
private uint Size;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
KsOpen = KinectSensor.GetDefault();//Kinect v2感測器獲取
frameDes = KsOpen.ColorFrameSource.FrameDescription;
//在全屏模式RGB攝像頭的位圖格式數據流的數據(1920×1080像素)
Bmp = new Bitmap(frameDes.Width , frameDes.Height ,PixelFormat.Format32bppRgb);
Rect = new Rectangle(0, 0, frameDes.Width, frameDes.Height);
Size = (uint)(frameDes.Width * frameDes.Height * 4);
colorReader = KsOpen.ColorFrameSource.OpenReader();
colorReader.FrameArrived += colorReader_FrameArrived;
KsOpen.Open();//開啟Kinect 使用它
}
private void colorReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
//throw new NotImplementedException();
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
//.NET Compact Framework 提供 LockBits 方法的支援
//這個方法可讓您在未受管理的記憶體緩衝區中操作點陣圖的像素陣列
//將點陣圖中的像素換成來自緩衝區的像素。
BitmapData cBitmapData = Bmp.LockBits(Rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
//換言之,就是將 Bitmap 鎖定在系統記憶體內
//LockBits參數
/*
LockBits(System.Drawing.Rectangle,
System.Drawing.Imaging.ImageLockMode,
System.Drawing.Imaging.PixelFormat);
*/
colorFrame.CopyConvertedFrameDataToIntPtr(cBitmapData.Scan0, Size, ColorImageFormat.Bgra);
Bmp.UnlockBits(cBitmapData);
// 相對於y軸上對pictureBox物件做左右翻轉
Bmp.RotateFlip(RotateFlipType.Rotate180FlipY);
pictureBox1.Image = Bmp;
}
}
}
}
不過你在測試完之後會發現有幾個問題需要修正
第一.影像畫面有點不穩定
第二.只顯示在某一區塊(右上角還左上角的樣子)
手靠近感測器 畫面
原因是因為
PictureBoxSizeMode.Normal:
默認情況下,在Normal 模式中,
Image 置於PictureBox 的左上角,
凡是因過大而不適合PictureBox 的任何圖像部分都將被剪裁掉
PictureBoxSizeMode這個列舉型態提供總共五種參數給你作修正
若沒設定 默認就為 Normal 喔!!!!
PictureBoxSizeMode.StretchImage:
使用StretchImage 值會使圖像拉伸或收縮,較適合PictureBox,方便我們看到完整畫面喔。
PictureBoxSizeMode.CenterImage:
使用CenterImage 值會使圖像居於工作區的中心。
PictureBoxSizeMode.Zoom:
使用Zoom 的值可以使圖像被拉伸或收縮以適應PictureBox;但是仍然保持原始寬高比。
PictureBoxSizeMode.AutoSize:
使用AutoSize 值會使控件調整大小,以便總是適合圖像的大小
在經過多次測試後
發現很長跳出此錯誤訊息
到底發生捨麼問題了 真是God!!!!
他是說需要多加一個 判別 colorFrame 是否為 null 的判斷
那我們就加吧
修正過後的
最後階段code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Kinect; // for Kinect SDK
using System.Drawing.Imaging; // for PixelFormat
namespace KinectV2_WindowsFormsApplication
{
public partial class Form1 : Form
{
private KinectSensor KsOpen = null;//啟動Kinect感測器 ...........................1.a
private FrameDescription frameDes = null;//影格描述(顏色源之frame接口)................2.a
private ColorFrameReader colorReader;//彩屏閱讀器界面框架(宣告彩色閱讀器)................3.a
private Bitmap Bmp; // 給影像pictureBox物件做承載
//private uint Size;
private UInt32 Size;
private Rectangle Rect;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
KsOpen = KinectSensor.GetDefault();//Kinect v2感測器獲取(獲得傳感器的默認)............1.b
frameDes = KsOpen.ColorFrameSource.FrameDescription;//獲得從傳感器接收到的彩色數據源...2.b
//RGB攝像頭的位元圖格式數據流的數據(1920×1080像素)
Bmp = new Bitmap(frameDes.Width , frameDes.Height ,PixelFormat.Format32bppRgb);
Rect = new Rectangle(0, 0, frameDes.Width, frameDes.Height);
Size = (uint)(frameDes.Width * frameDes.Height * 4);
//this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
//this.pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
//this.pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
colorReader = KsOpen.ColorFrameSource.OpenReader();//從感測器接收到的彩色數據源中開啟彩色Reader.......3.b
colorReader.FrameArrived += colorReader_FrameArrived;
KsOpen.Open();//開啟Kinect 使用它......................................................1.c
}
private void colorReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
//throw new NotImplementedException();
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
if (colorFrame != null)
{
//.NET Compact Framework 提供 LockBits 方法的支援
//這個方法可讓您在未受管理的記憶體緩衝區中操作點陣圖的像素陣列
//將點陣圖中的像素換成來自緩衝區的像素。
BitmapData cBitmapData = Bmp.LockBits(Rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
//換言之,就是將 Bitmap 鎖定在系統記憶體內
//LockBits參數
/*
LockBits(System.Drawing.Rectangle,
System.Drawing.Imaging.ImageLockMode,
System.Drawing.Imaging.PixelFormat);
*/
colorFrame.CopyConvertedFrameDataToIntPtr(cBitmapData.Scan0, Size, ColorImageFormat.Bgra);
Bmp.UnlockBits(cBitmapData);
// 相對於y軸上對pictureBox物件做左右翻轉
Bmp.RotateFlip(RotateFlipType.Rotate180FlipY);
pictureBox1.Image = Bmp;
}
}
}
}
}
希望對相關開發者有幫助
------------------------------------------------------------------------------------------------------
PictureBoxSizeMode部分參考部落格
【C#圖解】PictureBox.SizeMode 屬性 作者:銀月術
http://blog.csdn.net/moonsilvering/article/details/5940506
Bitmap部分代換問題請教於
微軟MVP
Vangos Pterneas
可以請問一下kinectV2的深度圖如何用在windows form
回覆刪除