OpenNI 2 VideoStream 與 Device 的設定與使用

之前的《OpenNI 2 基本程式範例》一文,基本上是一個最簡單、OpenNI 2 讀取深度的範例;而之後的《OpenNI 2 的錯誤處理》,則是針對 OpenNI 2 所採用的錯誤處理方法,做一個補充。接下來這一篇呢,則是在《OpenNI 2 基本程式範例》中,讀取深度的範例程式的基礎上,加上彩色影像的讀取,並說明如何針對建立出來的 VideoStream 做進一步的參數設定。

而最後,也會稍微帶一下,要怎樣把 OpenNI 2 讀到的影像資料,轉換成其他函式庫,例如 OpenCV 或 Qt 專用的格式。


讀取彩色影像

一般狀態下,OpenNI 2 要同時讀取彩色影像和深度影像,算是相當地簡單。程式的寫法,基本上就和讀取深度影像時相同,只要把彩色的 VideoStream 加上去就好了~而加上厚的程式,基本上就如下:

// STL Header#include <iostream>
 
// 1. include OpenNI Header
#include "OpenNI.h"
 
int main( int argc, char** argv )
{
// 2. initialize OpenNI
openni::OpenNI::initialize();
 
// 3. open a device
openni::Device devAnyDevice;
devAnyDevice.open( openni::ANY_DEVICE );
 
// 4. create depth stream
openni::VideoStream streamDepth;
streamDepth.create( devAnyDevice, openni::SENSOR_DEPTH );
streamDepth.start();
 
// 4a. create color stream
openni::VideoStream streamColor;
streamColor.create( devAnyDevice, openni::SENSOR_COLOR );
streamColor.start();

 
// 5 main loop, continue read
openni::VideoFrameRef frameDepth;
openni::VideoFrameRef frameColor;
for( int i = 0; i < 100; i )
{
// 5.1 get frame
streamDepth.readFrame( &frameDepth );
streamColor.readFrame( &frameColor );
 
// 5.2 get data array
const openni::DepthPixel* pDepth
= (const openni::DepthPixel*)frameDepth.getData();
const openni::RGB888Pixel* pColor
= (const openni::RGB888Pixel*)frameColor.getData();
 
// 5.3 output the depth value of center point
int idx = frameDepth.getWidth() * ( frameDepth.getHeight() 1 ) / 2;
std::cout << pDepth[idx]  << "( "
<< (int)pColor[idx].r << ","
<< (int)pColor[idx].g << ","
<< (int)pColor[idx].b << ")"
<< std::endl;
}
 
// 6. close
streamDepth.destroy();
streamColor.destroy();
devAnyDevice.close();
 
// 7. shutdown
openni::OpenNI::shutdown();
 
return 0;
}

其中,黃底的部分,就是針對彩色影像做處理的部分了。而和深度影像主要不同的地方,大致上只有兩個:一個是在呼叫 VideoStreamcreate() 函式的時候,是要指定感應器類型為 SENSOR_COLOR;再來就是深度影像的每一個像素的資料都是 DepthPixel 這個型別,而彩色影像的像素資料,則是 RGB888Pixel 這個型別RGB888Pixel 實際上是一個資料結構,裡面有 rgb 三個 unsigned char、也就是 0-255 的值,分別代表該點的紅、綠、藍的色彩。

而把程式做了像上面一樣的修改後,在執行的時候,除了會輸出畫面中央點的深度值後,也會跟著輸出該點的色彩的值了~

另外,在有多個 VideoStream 的情況下,OpenNI 另外也還有提供 OpenNI::waitForAnyStream() 這個函式可以用來等所指定的 VideoStream 陣列,當其中任一個有更新後,再繼續執行;而 VideoStream 另外也有提供所謂的 Listener 的設計,可以把程式寫成當讀取到新的資料的時候,就去做指定的事情,算是一種事件驅動(event driven)的開發模式。這兩種使用方法,基本上算是 OpenNI 2 裡面提供的別種資料存取的模式,在這邊就跳過,之後有機會再講吧。


VideoStream 的模式設定

上面的範例,算是已經把彩色影像和深度影像同時讀取出來了。不過在繼續、把他們真的畫出來之前,這邊先來想一下 OpenNI 2 的一些 VideoStream 模式設定的方法;主要的目的呢,就是根據需求來調整得到的影像的解析度了~

在 OpenNI 2 的架構下,要讀取深度、彩色影像,基本上都是先建立出要使用的 Device 後,再個別去建立出所需要的 VideoStream;在概念上來說,OpenNI 2 的 VideoStream 有點接近 OpenNI 1.x 的 Map Generator。而如果要設定影像的解析度等資訊的話,基本上也是要針對 VideoStream 來進行操作。

以比較常會修改到的解析度、FPS 來說,在 OpenNI 2 裡,是把它包成一個 openni::VideoMode 的類別,來統一處理。透過 VideoMode 的物件,以及 VideoStream 本身的 getVideoMode()setVideoMode() 函式,就可以簡單地取得/設定 VideoStream 的相關參數。下面就是一個讀取目前設定的的例子:

// 4. create depth stream
openni::VideoStream streamDepth;
streamDepth.create( devAnyDevice, openni::SENSOR_DEPTH );

// output basic video information
openni::VideoMode vmMode = streamDepth.getVideoMode();
cout << "Video Mode : " << vmMode.getResolutionX();
cout << " * " << vmMode.getResolutionY();
cout << " @ " << vmMode.getFps() << "FPS";
switch( vmMode.getPixelFormat() )
{
case openni::PIXEL_FORMAT_DEPTH_1_MM:
cout << " , Unit is 1mm" << endl;
break;
 
case openni::PIXEL_FORMAT_DEPTH_100_UM:
cout << " , Unit is 100um" << endl;
break;
}

上面的程式碼片段,會讀取出目前 VideoStream 的模式,並把他輸出。而從程式裡可以看的出來,VideoMode 它包含的資訊,除了影像的寬、高、FPS 外,也還有每一個像素的格式;以深度影像來說,主要應該就是使用以 1mm 為單位的 PIXEL_FORMAT_DEPTH_1_MM 或以 100um 為單位的 PIXEL_FORMAT_DEPTH_100_UM(另外還有兩種以 shift 為名的格式,不太確定用途),彩色影像的話,則是以 PIXEL_FORMAT_RGB888PIXEL_FORMAT_YUV422 為主(也還有其他的格式)

而如果是要進行設定的話,則大概會是像下面這個樣子:

// set video mode
openni::VideoMode vmMode;
vmMode.setFps( 30 );
vmMode.setResolution( 640, 480 );
vmMode.setPixelFormat( openni::PIXEL_FORMAT_DEPTH_100_UM );
if( streamDepth.setVideoMode( vmMode ) == openni::STATUS_OK )
{
// OK
}

如果成功的話,這樣就可以把深度影感應器的影像,設定成為 640×480、30FPS,並以 100um 為單位了~

當然,每款感應器可以設定的解析度參數都是有限的,並不能隨便給;而如果要知道目前這個 VideoStream 所對應的感應器支援那些模式,則可以透過 getSensorInfo() 來取得感應器的參數,他的型別是 openni::SensorInfo,他提供了一個 getSupportedVideoModes() 的函式,可以取得所有支援的 VideoMode 的陣列。下面就是一個範例(這邊把 openni 和 std 的 namespace 省略了)

const SensorInfo& rInfo = streamDepth.getSensorInfo();
const Array<VideoMode>& aModes = rInfo.getSupportedVideoModes();
for( int i = 0; i < aModes.getSize(); i )
{
const VideoMode& rMode = aModes[i];
cout << "Video Mode : " << rMode.getResolutionX();
cout << " * " << rMode.getResolutionY();
cout << " @ " << rMode.getFps() << "FPS";
switch( rMode.getPixelFormat() )
{
case PIXEL_FORMAT_DEPTH_1_MM:
cout << " , Unit is 1mm" << endl;
break;
 
case PIXEL_FORMAT_DEPTH_100_UM:
cout << " , Unit is 100um" << endl;
break;
}
}

這樣的程式碼執行後,就可以把這個深度感應器所支援的所有 VideoMode 都印出來了~下面就是 Heresy 的 Asus Xtion Pro Live 的測試結果:

Video Mode : 320 * 240 @ 30FPS , Unit is 1mm
Video Mode : 320 * 240 @ 30FPS , Unit is 100um
Video Mode : 320 * 240 @ 60FPS , Unit is 1mm
Video Mode : 320 * 240 @ 60FPS , Unit is 100um
Video Mode : 640 * 480 @ 30FPS , Unit is 1mm
Video Mode : 640 * 480 @ 30FPS , Unit is 100um
Video Mode : 320 * 240 @ 25FPS , Unit is 1mm
Video Mode : 320 * 240 @ 25FPS , Unit is 100um
Video Mode : 640 * 480 @ 25FPS , Unit is 1mm
Video Mode : 640 * 480 @ 25FPS , Unit is 100um

基本上,主要就是幾種基本參數的排列組合,全部列出來還滿多種的。

而如果是 Kinect for Xbox 360 感應器的話,支援的模式變化就比較少了,只有三種:

Video Mode : 640 * 480 @ 30FPS , Unit is 1mm
Video Mode : 320 * 240 @ 30FPS , Unit is 1mm
Video Mode : 80 * 60 @ 30FPS , Unit is 1mm

不過說實話…Heresy 這邊覺得滿討厭的一點,是 OpenNI 居然還自己土法煉鋼、自己寫了一個 Array,而沒有用 STL 的版本…這點就有點搞不懂他們在想啥了。

至於彩色影像的部分,基本上也可以用類似的方法來取得;不過就是 getPixelFormat() 的部分,要針對彩色影像的 PixelFormat 來做額外的處理了~

而除了 VideoMode 之外,VideoStream 也還有提供一些介面,可以取得一些額外的資訊,這邊 Heresy 大概選一些列一下:

此外,VideoStream 也還有提供一些其他的介面,可以做資料的控制;像是透過 setMirroringEnable() 可以用來控制取得的影像是否要做鏡像處理,透過 setCropping() 則可以設定影像的裁切範圍,不過在這邊就不詳細說明了,有需要的可以自行參考官方文件。

比較特別的是,如果是針對彩色影像的話,OpenNI 2 的 VideoStream 也提供了 getCameraSettings() 這個函式,可以取得 openni::CameraSetting 的物件,藉此控制攝影機的白平衡、以及自動曝光的開關。


彩色影像與深度影像的視角校正

基本上,不管是 Microsoft Kinect 還是 ASUS Xtion Pro Live,上面的彩色攝影機、和深度攝影機,都是獨立、位置不同的感應器,所以所取得的視角,是不一樣的。

所以如果在沒有特殊處理的情況下、直接把彩色影像和深度影像重疊在一起,就會發現兩張圖會有一些位置上的不一致;像右圖就是把深度影像和彩色影像直接重疊的結果,可以明顯地看的出來,右上角的日光燈,位置位移算是滿明顯的。

在 OpenNI 1.x 的時候,Heresy 有寫過一篇《透過 OpneNI 合併 Kinect 深度以及彩色影像資料》,算是專門在講這部分的設定。而在 OpenNI 2 的架構下,雖然方法不一樣,但是一樣是要做相關的設定,才可以讓兩者的位置更符合的。

在 OpenNI 2 的架構,要進行視角的校正,是要呼叫 Device 所提供的 setImageRegistrationMode() 這個函式,來進行校正方式的設定;而在目前的 OpenNI 2 裡,只有提供「不要校正」(IMAGE_REGISTRATION_OFF)和「把深度對到彩色影像的位置」(IMAGE_REGISTRATION_DEPTH_TO_COLOR)這兩種模式可以使用。

由於考慮到可能不是每一款感應器,都有支援視角校正的功能,所以在設定前,最好也先透過 DeviceisImageRegistrationModeSupported() 這個函式來確認是否支援;所以最後的程式寫法,就是如下:

if( devAnyDevice.isImageRegistrationModeSupported( IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
{
devAnyDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
}

而設定完之後,就會發現深度影像整個往內縮一圈、並且位置和彩色影像對得更好了~

 


將資料轉換給其他函式庫使用

到這邊為止,已經描述了該怎麼讀取深度與彩色資訊了。但是實際上,由於 OpenNI 本身沒有影像處理、顯示的能力,所以大部分的時候,應該都還是需要把 OpenNI 取得的影像資料,轉換成其他函式庫使用的型別。而由於 OpenNI 2 VideoStreamgetData() 所取得的資料,是很簡單的一維陣列,所以其實相當簡單就可以和大部分的函式庫互通。

OpenCV

以 OpenCV(官網)這套電腦視覺、影像處理的函式庫來說,他使用的影像格式是 cv::Mat 這種型別,我們可以透過他的建構子,簡單地把 VideoFrameRef 的資料,建立出一個 cv::Mat 的物件~以彩色影像來說,他的程式可以寫成:

const cv::Mat mImageRGB( mColorFrame.getHeight(), mColorFrame.getWidth(),
CV_8UC3, (void*)mColorFrame.getData() );

其中,mColorFrame 就是一個彩色影像的 VideoFrameRef 物件,透過這樣的程式,就可以建立出一個 OpenCV 的 Mat 物件 mImageRGB,型別是 CV_8UC3(8bit 正整數、3 channel),而資料就是連結到 mColorFrame 的資料了~不過這邊要注意的是,由於透過 VideoStreamgetData() 取得的資料實際上是 const 的,所以這邊雖然強制轉型成為 void* 來給 OpenCV 使用,但是還是要記得,這筆資料是不可以去修改的

另外,由於 OpenCV 內部彩色影像實際上是使用 BGR 的形式,而非 RGB 的形式,所以如果要做後續的處理的話,是需要把 RGB 影像轉換成 BGR 的~這樣的程式,基本上可以寫成:

cv::Mat cImageBGR;
cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );

透過這樣的程式,就可以把 RGB 排列的 mImageRGB,轉換成 OpenCV 慣用的 BGR 排列的 cv::Mat 物件 cImageBGR 了~

而深度影像的部分,由於型別不一樣,所以在建立的時候,要記得把 CV_8UC3 改成 CV_16UC1、也就是一個 channel 的 16bit 正整數的影像; 而之後如果要轉換成一般的 8bit 灰階影像的話,也可以透過 cv::Mat 本身提供的 convertTo() 函式來做轉換。

Qt

如果是以 Qt(官網)這個圖形介面函式庫的話,也是可以很簡單地,把彩色影像的資料轉換成 Qt 的 QImage 的形式~在程式的寫法上,也非常地相近,下面就是一個簡單的例子:

QImage qtImage( (const unsigned char*)mColorFrame.getData(),
mColorFrame.getWidth(), mColorFrame.getHeight(),
QImage::Format_RGB888 ) ) );

透過這樣的程式, qtImage 這個 QImage 的圖形,裡面的資料就會是 mColorFrame 的資料了~

而深度影像的部分,由於 QImage 應該是不像 OpenCV 一樣,有直接支援 16bit 的影像,所以如果要把深度影像轉換成 Qt 可以用的型式的話,可能就得自己先做好轉換了。

而實際上,大部分有影像功能的函式庫,應該也都有提供類似這樣,可以使用外部資料的方法,只要參考相關文件,要套用進去應該是不難的~


這篇基本上就先到這了。接下來,應該會是寫一下,用 OpenCV 和 Qt 來顯示 OpenNI 2 的資料的完整範例了~另外,現在都還是把這些資料當一般的影像用,當然之後還有把他們以 3D 的形式、畫出來的範例了。

而在之後,應該就是 Middleware library 的介紹了。

21 thoughts on “OpenNI 2 VideoStream 與 Device 的設定與使用”

  1. 補充:
    目前 Heresy 這邊測試的結果,很遺憾的,Microsoft Kinect 似乎無法使用這樣的視角修正的功能…這點在官方論壇上也有人提出來(參考:http://community.openni.org/openni/topics/how_can_i_align_with_kinect ,看來並非無解。

    就看之後 OpenNI 是否會去修改、讓官方版可以支援了。

  2. 你好Heresy
    由于大陆墙了很多你的很多篇文章,包括wordpress.com 上的博客,以及这里面的部分图片和文章,如 NITE2 基本使用,加上我这里网络不好,经常翻不过去(%>_additional deppendencies)
    对了是读 OpenNI 2 基本程式範例 这篇文章中的代码

  3. 咦,上面怎么少了

    由于大陆墙了很多你的很多篇文章,包括wordpress.com 上的博客,以及这里面的部分图片和文章,如 NITE2 基本使用,加上我这里网络不好,经常翻不过去,我只好在这篇文章下面提问了o(╯□╰)o

    是配置的问题:

    error LNK2019: unresolved external symbol __imp__oniFrameRelease referenced in function “public: void __thiscall openni::VideoFrameRef::release(void)” (?release@VideoFrameRef@openni@@QAEXXZ)

    等等等共有9处

    但是我包含了OpenNI2.lib文件了啊,这是哪儿出了差错。( Project Properties à Linker à Input—>additional deppendencies)
    对了是读 OpenNI 2 基本程式範例 这篇文章中的代码

    好像发现了一个漏洞,中的东西会消失

  4. to houqiqi

    unresolved external symbol 的 link error 一般基本上是由於找不到正確的 lib 檔造成的。
    請確定錯誤報告裡面,有沒有類似這樣找不到檔案的錯誤。
    並確認專案設定裡面,是否有設定正確的 Additional Library Directories(注意,32 / 64 位元是不一樣的)

  5. heresy 你好,我是win8 64位系统,vs2010,我真的不懂32/64位元的不同哎,不知道从哪儿改啊,配置时我装的是OpenNI64位的和NiTE64位的。
    「C/C 」的「Gerenal」的「Additional Include Directories」中直接填写的
    $(OPENNI2_INCLUDE64);$(NITE2_INCLUDE64)

    「Linker」的「Gerenal」的「Additional Library Directories」中填写的是 $(OPENNI2_LIB64);$(NITE2_LIB64)

    Linker的「Input」的「Additional Dependencies」中添加了OpenNI2.lib;NiTE2.lib;

    将OpenNI和NiTE的Register拷到了项目的下面,就是存有该项目的.vcxproj 的文件夹下

    将鼠标放在openni::OpenNI::initialize();上,是可以 go to definition的

    还有vs的错误报告是什么,不懂哎,是下面这个吗,build的时候出现的

    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniFrameRelease referenced in function “public: void __thiscall openni::VideoFrameRef::release(void)” (?release@VideoFrameRef@openni@@QAEXXZ)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniStreamStart referenced in function “public: enum openni::Status __thiscall openni::VideoStream::start(void)” (?start@VideoStream@openni@@QAE?AW4Status@2@XZ)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniStreamReadFrame referenced in function “public: enum openni::Status __thiscall openni::VideoStream::readFrame(class openni::VideoFrameRef *)” (?readFrame@VideoStream@openni@@QAE?AW4Status@2@PAVVideoFrameRef@2@@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniInitialize referenced in function “public: static enum openni::Status __cdecl openni::OpenNI::initialize(void)” (?initialize@OpenNI@openni@@SA?AW4Status@2@XZ)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniShutdown referenced in function “public: static void __cdecl openni::OpenNI::shutdown(void)” (?shutdown@OpenNI@openni@@SAXXZ)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceCreateStream referenced in function “public: enum openni::Status __thiscall openni::VideoStream::create(class openni::Device const &,enum openni::SensorType)” (?create@VideoStream@openni@@QAE?AW4Status@2@ABVDevice@2@W4SensorType@2@@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniStreamIsPropertySupported referenced in function “public: bool __thiscall openni::VideoStream::isPropertySupported(int)const ” (?isPropertySupported@VideoStream@openni@@QBE_NH@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniStreamGetSensorInfo referenced in function “private: void __thiscall openni::VideoStream::_setHandle(struct _OniStream *)” (?_setHandle@VideoStream@openni@@AAEXPAU_OniStream@@@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniStreamDestroy referenced in function “public: void __thiscall openni::VideoStream::destroy(void)” (?destroy@VideoStream@openni@@QAEXXZ)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceOpen referenced in function “public: enum openni::Status __thiscall openni::Device::open(char const *)” (?open@Device@openni@@QAE?AW4Status@2@PBD@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceIsPropertySupported referenced in function “public: bool __thiscall openni::Device::isPropertySupported(int)const ” (?isPropertySupported@Device@openni@@QBE_NH@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceIsCommandSupported referenced in function “public: bool __thiscall openni::Device::isCommandSupported(int)const ” (?isCommandSupported@Device@openni@@QBE_NH@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceGetInfo referenced in function “private: enum openni::Status __thiscall openni::Device::_setHandle(struct _OniDevice *)” (?_setHandle@Device@openni@@AAE?AW4Status@2@PAU_OniDevice@@@Z)
    1>2 test 2.obj : error LNK2019: unresolved external symbol __imp__oniDeviceClose referenced in function “public: void __thiscall openni::Device::close(void)” (?close@Device@openni@@QAEXXZ)
    1>F:编着玩的201322 test 2Debug2 test 2.exe : fatal error LNK1120: 14 unresolved externals

    我现在所有的改动就是上面的,其他就不知道该怎么办了,求助啊

    现在可不可以装32位的OpenNI和NiTE,然后按教程匹配,这样可以吗(64位系统真是不方便啊)

    谢谢啊

  6. 对了,我在那个项目中配置了OpenCV,OpenCV是可以运行的,这对OpenNI的配置有没有影响?就是在linker的「Input」的「Additional Dependencies」中添加了有很多OpenCV的lib文件, release模式时也加了一些lib文件

    在VC 的include directories 中加了OpenCV的include的地址,libraries directories中加了其lib文件的地址

  7. 我运行NiViewer.exe,运行不了,出现了R6025 pure virtual function call,虚函数报错,好像是加载.dll文件出现了错误,是OpenNI的问题还是系统的问题,还是其他的问题,使得OpenNI配置不成功

  8. 刚刚我装了32位的OpenNI,安装并配置后是可以Build的,但是,debug时遇到了0xc000007b程序无法正常启动的问题,好像是系统的缘故了,现在该怎么办啊

  9. 谢谢heresy,问题已经解决了,怎么也不会想到竟然是vs2010的问题,重装一下就好了,谢谢啦

  10. 请问houqiqi,必须得重装vs才能解决吗?我的是win7 64位,vs2010,也出现了你说的那个链接问题,不知道怎么解决啊,请问您的具体解决步骤是什么?谢谢啦。

  11. 請問houqiqi
    我也遇到了同樣問題,你是怎麼解決的,我是vs2012

  12. heresy,你好!看了你的文章,收获很大,谢谢~~有一个问题,isImageRegistrationModeSupported在矫正视角,如果这个函数返回false说明设备不支持?是不是就没有办法改变让设备支持了?我的意思是返回false,能不能通过设置设备的参数来让其支持矫正视角?

  13. @solo

    不知道你的感應器是哪一款?
    如果是 Kinect 的話,最新版本的 OpenNI 2.2 應該也有支援了。 建議先更新試試看。

  14. heresy 你好
    我是装的openni2 有一段用来显示深度信息和对应的彩色R、G、B数值的程序,但一运行VS2010就停止工作.
    具体问题是:有未经处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
    请问怎么解决?

  15. to whh

    個人建議可以試著在程式內加上錯誤檢查的程式,確認一下 OpenNI 的相關物件是否建立成功。

  16. Q1 請問 array可以儲存成矩陣?
    Q2 .frameDepth.getWidth() * ( frameDepth.getHeight() 1 ) / 2;
    請問這行是讀出中心點?
    感謝

  17. Heresy 大大
    我想請問 KINET 都是存成陣列? 可以使用矩陣?
    因為我想在一張圖 使用個別輸入 X座標 和 Y座標
    得到 RGB 和 深度
    我參考你的程式 for( int i = 0; i < 100; i ) 這行拿掉 但 出現問題 int idx = frameDepth.getWidth() * ( frameDepth.getHeight() 1 ) / 2; 這行是讀出中心點 但我想讀其他的 我就用 比如 X=100 Y=100 int idx = frameDepth.getWidth(100) * ( frameDepth.getHeight(100) ; 執行出 0 (0 0 0)

  18. to 新學KINECT

    1. OpenNI 2 讀取出來的就是一個陣列。
    如果要轉換成矩陣的形式,則需要自己轉換。

    2. 這邊只是概算而已

  19. to 新學KINECT

    index 的計算方式基本上是 y * w x。
    以 100, 100 來說,基本上就是 100 * frameDepth.getWidth() 100

  20. 感謝您Heresy 大大
    我問題終於解決 我可以加您 FB?
    因為我沒有學長 買書都是C sahp 比較不懂
    真的很感謝 我卡了2個禮拜 買書來看
    一直以為是矩陣問題 感謝

發佈回覆給「mopackh50346」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。