国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于kinect的人體識(shí)別技術(shù)的一些改進(jìn)

2012-04-29 23:23:00林填鋒楊潔霞
電腦知識(shí)與技術(shù) 2012年21期

林填鋒 楊潔霞

摘要:kinect工作模式的核心是人體識(shí)別,該文研究了kinect人體識(shí)別的實(shí)現(xiàn)過(guò)程,并對(duì)Microsoft SDK提供的代碼作了改進(jìn)。

關(guān)鍵詞:人體識(shí)別;深度識(shí)別;骨骼追蹤

中圖分類號(hào):TP391文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2012)21-5220-04

Kinect based Human Identification Technology Improvement

LIN Tian-feng, YANG Jie-xia

(Guangzhou University, Guangzhou 510006, China)

Abstract: In the kinect game, the most important link is the identification of body, This article uses the Microsoft SDK development of hu man identification system to do specific research and implementation.

Key words: the identification of body;deep identification; on the track of the bones

kinect是微軟在2010年6月14日推出,能用于Xbox360的游戲機(jī)設(shè)備。通過(guò)kinect,玩家可以利用肢體或者聲音去操作各樣的物品,開(kāi)創(chuàng)了一種新的游戲模式,使得游戲與運(yùn)動(dòng)相結(jié)合。這種新的游戲模式展現(xiàn)了人機(jī)交互的理念,添加了游戲樂(lè)趣,將會(huì)是游戲一個(gè)新的里程碑。

kinect的工作模式主要是識(shí)別人體及相關(guān)的動(dòng)作,而識(shí)別人體的最主要核心就是骨骼。通過(guò)骨骼的追蹤,kinect把人體的動(dòng)作掃描到計(jì)算機(jī)上,并做相關(guān)的模擬及操作。原Microsoft SDK提供的代碼,下部分沒(méi)有連接到脊椎,腳部在系統(tǒng)識(shí)別時(shí),腳部線條偶爾會(huì)出現(xiàn)識(shí)別出錯(cuò)的現(xiàn)象,該文研究了kinect人體識(shí)別的實(shí)現(xiàn)過(guò)程,對(duì)此作了改進(jìn)。

1 kinect技術(shù)及工作原理

Kinect主要包括三個(gè)方面,kinect傳感器、深度識(shí)別技術(shù)和人體骨骼追蹤技術(shù)。

1.1 kinect傳感器

kinect有三個(gè)攝像頭,中間是RGB彩色攝像頭,兩邊是紅外線發(fā)射器和CMOS攝像機(jī),分別用于發(fā)射紅外線和接受數(shù)據(jù)。其工作過(guò)程是通過(guò)CMOS紅外傳感器來(lái)感知攝像頭前面的環(huán)境,使用黑白光譜的方式來(lái)判斷前面對(duì)應(yīng)的物品與傳感器的物理距離,收集攝像頭視野里的每一點(diǎn),然后每30MS整合出一幅深度圖像,并且用3D的效果模型顯示出來(lái)。

1.2深度識(shí)別技術(shù)

kinect在生成的深度圖像上,采用分隔策略,將人體從深度圖像中的背景環(huán)境中區(qū)分出來(lái),進(jìn)行像素級(jí)評(píng)估,辨別出人體的不同部位,同時(shí)返回深度圖像到設(shè)備上。采用3D深度攝像機(jī)技術(shù),可以捕捉到人所在的空間位置。原理是紅外線感應(yīng),Kinect上有1組3D深度感應(yīng)攝像頭,首先通過(guò)紅外線發(fā)射器發(fā)出一種不可見(jiàn)鐳射光,這個(gè)光線經(jīng)過(guò)擴(kuò)散片分布在測(cè)量的空間內(nèi),當(dāng)鐳射光射到人體之后會(huì)形成反射斑點(diǎn),另外一個(gè)紅外線攝像機(jī)對(duì)這些反射斑點(diǎn)進(jìn)行記錄,通過(guò)芯片合成出3D深度信息的圖像。

1.3人體骨骼追蹤技術(shù)

識(shí)別到3D圖像深度信息后,kinect通過(guò)渲染數(shù)據(jù),并計(jì)算得到人體主要的20個(gè)骨骼位置,通過(guò)kinect紅外掃描,計(jì)算機(jī)程序計(jì)算并掌握玩家身形輪廓與其肢體位置,以此來(lái)判斷玩家的姿勢(shì),從而捕捉到人的動(dòng)作,現(xiàn)在kinect由于視野和識(shí)別的效果情況下,最佳狀態(tài)支持2個(gè)人的骨骼捕捉。通過(guò)kinect的深度圖像,根據(jù)系統(tǒng)某像素,來(lái)判定人體的20個(gè)節(jié)點(diǎn),生成骨骼系統(tǒng),以實(shí)現(xiàn)對(duì)人體的識(shí)別功能。

2 kinect的人體識(shí)別技術(shù)的實(shí)現(xiàn)與改進(jìn)

2.1彩色圖像顯示

彩色圖像是kinect所攝影到的真實(shí)場(chǎng)景圖像,在設(shè)備初始化完成后,系統(tǒng)通過(guò)線程來(lái)實(shí)現(xiàn)對(duì)彩色圖像的加工以及將其顯示到彩色控件上,初始化彩色圖像的數(shù)據(jù),綁定數(shù)據(jù)流,提取數(shù)據(jù)流,讀取當(dāng)前幀的數(shù)據(jù),將數(shù)據(jù)以位圖形式顯示到控件上,最后釋放當(dāng)前幀,等待下一幀的數(shù)據(jù),并重復(fù)以上的操作。

2.2深度圖像數(shù)據(jù)處理

當(dāng)設(shè)備初始化完畢,系統(tǒng)通過(guò)輪詢的模式,來(lái)讀取深度圖像數(shù)據(jù),并處理數(shù)據(jù),通過(guò)使用NuiImageStreamOpen()函數(shù)打開(kāi)數(shù)據(jù)流,獲取當(dāng)前幀的數(shù)據(jù),并且指出下一幀數(shù)據(jù)的等待時(shí)間,如果有新的數(shù)據(jù)幀到來(lái),或者超過(guò)等待時(shí)間,函數(shù)返回。當(dāng)函數(shù)成功返回時(shí),則程序處理數(shù)據(jù),創(chuàng)建一個(gè)深度數(shù)據(jù)處理的線程,在線程中調(diào)用CSkeletalViewerApp:Nui_GotDepthAlert()來(lái)加工深度數(shù)據(jù),在Nui_GotDepthAlert()中,調(diào)用NuiImageStreamGetNextFrame()獲取當(dāng)前幀的深度圖像數(shù)據(jù),其次Nui_GotDepthAlert()返回框架鎖防止底層數(shù)據(jù)的變化,最后調(diào)用DrawDevice類中定義的DrawFrame()函數(shù)來(lái)緩沖數(shù)據(jù),并把數(shù)據(jù)處理后顯示在應(yīng)用上。深度圖像控件實(shí)現(xiàn)如圖1所示。

圖1深度圖像控件實(shí)現(xiàn)圖

2.3生成骨骼圖

骨骼架構(gòu)。

骨骼圖生成是本應(yīng)用的重點(diǎn),在此應(yīng)用中,生成的骨骼圖,是由數(shù)據(jù)渲染出的點(diǎn)和線條構(gòu)成的骨骼架構(gòu)圖。當(dāng)系統(tǒng)檢測(cè)追蹤到的人體時(shí),先生成深度圖,再通過(guò)dwFrameNumber成員變量NUI_SKELETON_FRAME結(jié)構(gòu)所包含了對(duì)于深度圖像的幀處理,創(chuàng)造骨骼框架,骨骼的API消息處理每一個(gè)深度事件消息,以便應(yīng)用程序處理數(shù)據(jù)。接收骨骼數(shù)據(jù)存儲(chǔ)在SDK的一個(gè)數(shù)據(jù)結(jié)構(gòu)中,如下:

typedef struct _NUI_SKELETON_DATA

{

NUI_SKELETON_TRACKING_STATE eTrackingState; DWORD dwTrackingID;

DWORD dwEnrollmentIndex;

DWORD dwUserIndex;

Vector4 Position;

Vector4 SkeletonPositions[NUI_SKELETON_POSITION_COUNT];

NUI_SKELETON_POSITION_TRACKING_STATE

eSkeletonPositionTrackingState[NUI_SKELETON_POSITION_COUNT]; DWORD dwQualityFlags;} NUI_SKELETON_DATA;

參數(shù)eTrackingState表明當(dāng)前被追蹤的人體類型,dwTrackingID是人體識(shí)別的ID,如果ID等于0,則表明當(dāng)前人體不被追蹤和識(shí)別,當(dāng)ID在1到6之間,則說(shuō)明當(dāng)前人體被追蹤。成員變量NUI_SKELETON_POSITION_COUNT為人體骨骼數(shù)量,返回的骨骼數(shù)據(jù)為20個(gè)節(jié)點(diǎn),使得明確了人體的骨骼位置,在程序中,通過(guò)使用NUI_SKELETON_POSITION_INDEX()函數(shù)可以枚舉人體的骨骼。

繪制骨骼圖,骨骼控件實(shí)現(xiàn)如圖2所示。

同深度數(shù)據(jù)處理一樣,生成骨骼圖,也需要?jiǎng)?chuàng)建一個(gè)事件和線程,并且在線程里完成。在線程N(yùn)ui_ProcessThread()中,當(dāng)骨骼事件發(fā)生時(shí),系統(tǒng)調(diào)用函數(shù)CskeletalViewerApp::Nui_GotSkeletonAlert(),通過(guò)其內(nèi)部的函數(shù)來(lái)完成對(duì)骨骼圖進(jìn)行繪制,Nui_GotSkeleto nAlert()函數(shù)的設(shè)計(jì)思想如下:

1)獲取數(shù)據(jù),調(diào)用NuiSkeletonGetNextFrame()函數(shù)獲取當(dāng)前幀骨骼數(shù)據(jù),其函數(shù)定義類似于彩色圖像數(shù)據(jù)和深度圖像數(shù)據(jù),如果失敗則跳出Nui_GotSkeletonAlert()函數(shù),并返回FALSE。

檢測(cè)數(shù)據(jù)的完整性,20個(gè)節(jié)點(diǎn)的信息是否存在,因?yàn)樵谙到y(tǒng)運(yùn)行時(shí),每一次處理深度圖像時(shí),返回的數(shù)據(jù)中不一定有人體的骨骼數(shù)據(jù),所以,需要判別當(dāng)前所收到的數(shù)據(jù)中,是否存在著人體的骨骼信息,如果有,就判別是否存在人體的20個(gè)骨骼節(jié)點(diǎn)信息,如果失敗則返回FALSE,結(jié)束函數(shù)運(yùn)行,

2)平滑幀輸出,當(dāng)系統(tǒng)處理幀數(shù)據(jù)時(shí),如果按順序輸出幀數(shù)據(jù),顯示出的框架會(huì)出現(xiàn)抖動(dòng)現(xiàn)象,使得動(dòng)作不平滑,顯得僵硬。使用NuiTransformSmooth()函數(shù)平滑骨骼幀,消除抖動(dòng)現(xiàn)象,函數(shù)結(jié)構(gòu)如下:

m_d3dNui→NuiTransformSmooth(&Nuiskeleton,NULL);

3)繪制骨骼圖,獲取所需要的數(shù)據(jù)后,繪制出相關(guān)的骨骼圖像,顯示在骨骼圖像控件上,并且對(duì)其進(jìn)行追蹤識(shí)別,當(dāng)查找到骨骼數(shù)據(jù)時(shí),重新初始化定時(shí)器,并且調(diào)用CskeletalViewerApp中所定義的Nui_DrawSkeleton()函數(shù),來(lái)繪制目前已識(shí)別到的每個(gè)人體骨骼圖。代碼如下:

bool bBool = true;

//繪制已識(shí)別到的骨骼

for( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ )

{

if(Nuiskeleton.SkeletonData[i].eTrackingState== NUI_SKELETON_TRACKED&&Nuiskeleton.SkeletonData[i].eSkeletonPositionTrack ingState[NUI_SKELETON_POSITION_SHOULDER_CENTER] != NUI_SKELETON_POSITION_NOT_TRACKED)

{

Nui_DrawSkeleton( bBool, &Nuiskeleton.SkeletonData[i], GetDlgItem( m_hWnd, IDC_SKELETALVIEW ), i );

bBool = false;

}

}

Nui_DrawSkeleton()定義在CskeletalViewerApp類中,含有四個(gè)參數(shù),分別是:第一個(gè)是一個(gè)BOOL值,用于判別骨骼是否已存在;第二個(gè)是一個(gè)指向骨骼數(shù)組的指針,用于存儲(chǔ)骨骼數(shù)據(jù);第三個(gè)是一個(gè)句柄,用于識(shí)別控件的ID;第三個(gè)是一個(gè)整形數(shù),用于表明骨骼顯示顏色。

當(dāng)Nui_DrawSkeleton()第一次被調(diào)用時(shí),會(huì)先創(chuàng)建畫筆,用于來(lái)描繪骨骼之間的連線,線條的大小等于窗口寬度width除以80,與窗口的寬度成正比,這使繪畫出來(lái)的線條跟著窗口大小的改變而改變,使其界面美觀,代碼如下:

m_pPen[0] = CreatePen( PS_SOLID, width / 80, RGB(0, 0, 0) );

m_pPen[5] = CreatePen( PS_SOLID, width / 80, RGB( 32,32, 128 ) );

下一步,繪制骨骼坐標(biāo),從深度圖上取得深度圖坐標(biāo)轉(zhuǎn)換而來(lái),因?yàn)樯疃茸鴺?biāo)與骨骼的坐標(biāo)數(shù)據(jù)是基于不同的坐標(biāo)系統(tǒng),如以下代碼,返回的x,y就是骨骼相對(duì)于深度圖的坐標(biāo)。.

NUI_SKELETON_DATA * Skeldata;

int image_X = width;

int image_Y = height;

float fx=0,fy=0;

int i;

//繪制坐標(biāo)

for (i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)

{

NuiTransformSkeletonToDepthImageF( Skeldata→SkeletonPos[i], &fx, &fy );

m_Points[i].x = (int) ( fx * image_X + 0.5f );

m_Points[i].y = (int) ( fy * image_Y + 0.5f );

}

其次,當(dāng)數(shù)據(jù)轉(zhuǎn)換完成后,利用SDK枚舉值來(lái)確定各關(guān)節(jié)的坐標(biāo),開(kāi)始繪畫人體骨架,調(diào)用函數(shù)CskeletalViewerApp:: Nui_DrawSkeletonSeg ()來(lái)繪制,代碼如下所示(原Microsoft SDK例子中,下部分連接沒(méi)有連接到脊椎,腳部在系統(tǒng)識(shí)別時(shí),腳部線條偶爾會(huì)出現(xiàn)識(shí)別出錯(cuò)的現(xiàn)象,系統(tǒng)從腳心連接到脊椎,在腳部動(dòng)作識(shí)別時(shí),腳部線條識(shí)別相對(duì)原來(lái)比較準(zhǔn)確),連接方法為:

1)臀部、脊椎、肩部中心、頭部;

2)肩部中心、左肩部、左手肘、左手腕、左手心;

3)肩部中心、右肩部、右手肘、右手腕、右手心;

4)脊椎、臀部、左臀部、左膝蓋、左腳腕、左腳心;

5)脊椎、臀部、右臀部、右膝蓋、右腳腕、右腳心;

//使用Nui_DrawSkeletonSeg函數(shù)進(jìn)行節(jié)點(diǎn)連接

Nui_DrawSkeletonSeg(Skeldata,4,NUI_SKELETON_POSITION_HIP_CENTER,NUI_SKELETON_POSITION_SPINE,NUI_SKELE?TON_POSITION_SHOULDER_CENTER,NUI_SKELETON_POSITION_HEAD);

Nui_DrawSkeletonSeg(Skeldata,5,NUI_SKELETON_POSITION_SHOULDER_CENTER,NUI_SKELETON_POSITION_SHOUL

DER_LEFT,NUI_SKELETON_POSITION_ELBOW_LEFT,NUI_SKELETON_POSITION_WRIST_LEFT,NUI_SKELETON_POSI TION_HAND_LEFT);

Nui_DrawSkeletonSeg(Skeldata,5,NUI_SKELETON_POSITION_SHOULDER_CENTER,NUI_SKELETON_POSITION_SHOUL DER_RIGHT,NUI_SKELETON_POSITION_ELBOW_RIGHT,NUI_SKELETON_POSITION_WRIST_RIGHT,NUI_SKELETON_POSI TION_HAND_RIGHT);

Nui_DrawSkeletonSeg(Skeldata,6,NUI_SKELETON_POSITION_SPINE,NUI_SKELETON_POSITION_HIP_CENTER,NUI_SKELE TON_POSITION_HIP_LEFT,NUI_SKELETON_POSITION_KNEE_LEFT,NUI_SKELETON_POSITION_ANKLE_LEFT,NUI_SKELE TON_POSITION_FOOT_LEFT);

Nui_DrawSkeletonSeg(Skeldata,6,NUI_SKELETON_POSITION_SPINE,NUI_SKELETON_POSITION_HIP_CENTER,NUI_SKELE TON_POSITION_HIP_RIGHT,NUI_SKELETON_POSITION_KNEE_RIGHT,NUI_SKELETON_POSITION_ANKLE_RIGHT,NUI_SKELE TON_POSITION_FOOT_RIGHT);

再次,通過(guò)枚舉設(shè)置每個(gè)節(jié)點(diǎn)的顏色值,最后在Nui_DrawSkeleton中,用不同顏色的畫筆繪制每個(gè)關(guān)節(jié)點(diǎn),再按上面的連接方法,把各關(guān)節(jié)連接起來(lái),連接成功后刪除畫筆,代碼如下:

for (i = 0; i < NUI_SKELETON_POSITION_COUNT ; i++)

{

//判斷是否存在有效人體數(shù)據(jù)

if(Skeldata→eSkeletonPositionTrackingState[i]!= NUI_SKELETON_POSITION_NOT_TRACKED)

{

HPEN myPen;

myPen=CreatePen(PS_SOLID,9, g_Color [i]);

hOldObj=SelectObject(m_SkelDC,myPen);

MoveToEx( m_SkeDC, m_Poi[i].x, m_Poi[i].y, NULL );

LineTo( m_SkelDC, m_Poi[i].x, m_Poi[i].y );

SelectObject( m_SkelDC, hOldObj );

DeleteObject(myPen);

渲染圖像,調(diào)用CSkeletalViewerApp::Nui_DoDoubleBuffer()函數(shù)渲染骨骼圖像到顯示器上,使用緩沖的方式,把骨骼圖以位圖的方式渲染到窗口上,并釋放設(shè)備上下文。

2.4退出應(yīng)用

當(dāng)用戶關(guān)閉窗口時(shí),觸發(fā)了窗口類中的WM_CLOSE事件,在窗口函數(shù)中定義了WM_CLOSE事件的消息響應(yīng)函數(shù)DestroyWin dow(),指向并調(diào)用CSkeletalViewerApp::Nui_UnInit()來(lái)做清理工作,刪除設(shè)備上下文和位圖,畫筆,關(guān)閉所建立的線程。

3結(jié)束語(yǔ)

想開(kāi)發(fā)kinect游戲或者應(yīng)用,必須先了解知道kinect的人體識(shí)別,只有了解清楚才可以更好地實(shí)現(xiàn)kinect應(yīng)用程序,該文針對(duì)ki nect的開(kāi)發(fā)基礎(chǔ)---人體識(shí)別作了改進(jìn),為kinect應(yīng)用的開(kāi)發(fā)者提供了方便。

參考文獻(xiàn):

[1]周國(guó)慶,陳洪,馮人果.DirectX游戲編程[M].北京:清華大學(xué)出版社,2010.

[2] Microsoft公司.MFC與Windows編程[M].北京:北京大學(xué)出版社,2000.

[3]馬寧.Kinect_for_Windows_SDK開(kāi)發(fā)初體驗(yàn)[EB/OL]. [2012-04-20].http://www.cnblogs.com/aawolf/archive/2011/06/17/2083249.html.

闽侯县| 遂平县| 平谷区| 冀州市| 商南县| 商丘市| 宁安市| 囊谦县| 宜城市| 扎赉特旗| 天等县| 新乐市| 三明市| 新密市| 宜城市| 平原县| 呼玛县| 准格尔旗| 顺昌县| 双城市| 科尔| 定日县| 镇远县| 瑞丽市| 隆子县| 延庆县| 红河县| 砀山县| 白沙| 义乌市| 新营市| 鹰潭市| 舟曲县| 泌阳县| 曲水县| 文水县| 从化市| 错那县| 延长县| 玛纳斯县| 大兴区|