上篇文章我們介紹了SimpleOpenNI開發(fā)平臺搭建,今天小編繼續(xù)為大家講解用kinect繪制深度圖與繪制人體軀干實例具體操作過程!
一 、用kinect繪制深度圖
Kinect+OpenNI允許用戶獲得深度圖像,一個紅外發(fā)射頭負責發(fā)射紅外,另一個負責接受,這樣的話我們就獲得了背影射物體離攝像頭有多少個像素點,也就是有多遠。
在processing里面每一個工程被稱為sketch而不是一般軟件的Project因為Processing的程序運行起來更像是畫家在紙上畫的草圖,素描風明顯。
為了讓深度圖在電腦上顯示出來,獲得用戶想要的數(shù)據(jù),我們就必須導(dǎo)入OpenNI,目的是導(dǎo)入打包好OpenNI數(shù)據(jù),所以首先導(dǎo)入數(shù)據(jù)包(庫的思想)。
--------------------------------------------------------
import SimpleOpenNI.*;
---------------------------------------------------------
接下來我們聲明一個全局對象,context來和Kinect來取得數(shù)據(jù)聯(lián)系
--------------------------------------------------------
SimpleOpenNI context;
---------------------------------------------------------
接下來我們來看看setup()函數(shù),要知道一個事情,就是setup()函數(shù)里面所有的內(nèi)容只執(zhí)行一遍,而且只是程序一開始的階段才被執(zhí)行。
--------------------------------------------------------
void setup()
{
// 建立新的對象
context = new SimpleOpenNI(this);
// 使能深度影響
context.enableDepth();
// 創(chuàng)建一個這樣的尺寸,它可以保證裝下深度的一切信息
size(context.depthWidth(), context.depthHeight());
}
---------------------------------------------------------
接下來我們來看一下Draw()里面的 函數(shù),有關(guān)于draw()函數(shù),它是無限循環(huán)運行的,頻率是每秒60次。
-------------------------------------------------------
void draw()
{
//不斷更新來自Kinect Camera的數(shù)據(jù)
context.update();
// 繪制深度圖
image(context.depthImage(),0,0);
}
---------------------------------------------------------
Context.update()函數(shù)對每一幀的數(shù)據(jù)都有更新動作
運行sketch 的結(jié)果如圖所示:
代碼解析如下:
import SimpleOpenNI.*;
SimpleOpenNI context;
void setup()
{
// instantiate a new context
context = new SimpleOpenNI(this);
// enable depth image generation
context.enableDepth();
// create a window the size of the depth information
size(context.depthWidth(), context.depthHeight());
}
void draw()
{
// update the camera
context.update();
// draw depth image
image(context.depthImage(),0,0);
}
---------------------------------------------------------------------
如果知道了深度信息,你有什么想法?
這個問題很值得在這里,仔細的思考一下,你打算做點什么?
或者是現(xiàn)在你沒有太多想法,但是接下來的案例中我要求你必須有自己的想法,就算不會碼代碼。
二、 繪制人體軀干
首先呢,先要普及一下知識,有關(guān)于3D空間距離計算的知識,
在三D空間里,距離的計算,和我們在高中學(xué)得向量計算是一個道理的,下面從2D空間說起:
X1=2 X2=9
直線由兩個點構(gòu)成,坐標如上圖已給出。
----------------------------------(直角三角形關(guān)系)
--------------------------------(a的坐標距離表示)
---------------------------------(b的坐標距離表示)
--(同樣符合三角形邊的關(guān)系)
--------(過渡到2D空間距離)
關(guān)鍵就是3D空間距離,多加了一個Z坐標
上面那個公式就是3D空間里點之間里的公式。
那么怎么在代碼里實現(xiàn)計算3D空間兩點間距離。
首先,定義一個新的函數(shù)
distances3D( )
void distance3D(PVector point1, PVector point2)
{
}
在函數(shù)里面首先我們要添加一些變量來儲存x,y 和 z 的值,我們還需要一個變量來儲存最終的結(jié)果也就是返回值
float diff_x, diff_y, diff_z; // 儲存x,y,z的值
float distance; // 來儲存最后的返回值(結(jié)果也就是距離)
接下來計算兩個點之間的x,y,z的差值
diff_x = point1.x - point2.x;
diff_y = point1.y - point2.y;
diff_z = point1.z - point2.z;
之后就是簡單的計算
return distance; // return the distance as a float
整理之后的代碼就是:
float distance3D(PVector point1, PVector point2
){
float diff_x, diff_y, diff_z;
float distance;
diff_x = point1.x - point2.x;
diff_y = point1.y - point2.y;
diff_z = point1.z - point2.z;
distance = sqrt(pow(diff_x,2)+pow(diff_y,2)+pow(diff_z,2));
return distance;
}
寫好程序之后,運行結(jié)果就是這個深度圖與人體軀干的形態(tài),其中黑色是后加工的,人體顏色也是加工過的。
三、望有所思
看完這個例子千萬別無動于衷,這回你一定要有好的想法,比如你想獲得鍵盤映射、操控鍵盤、獲得鼠標映射、控制鼠標、或者是直接獲得圖形映射和控制圖形變化,或許你能寫出個好玩的游戲。
這個話題先放一放,貪吃蛇的平臺移植會很簡單,所以以后我們一定要試一試,最終的結(jié)果就是:用手勢控制蛇的運動方向從而控制蛇去吃更多的食物。
基礎(chǔ)教程這里做一個完結(jié),基礎(chǔ)教程完畢。請期待下幾期的更新!
評論
查看更多