Home People Research Blog Courses Links Search Download
NCHC

Blog

Blog 最新文章

  1. Gitlab CI/CD 簡單介紹
    2019/02/13 13:42
  2. Power-Z KT001 USB 電源量測器
    2019/01/30 10:57
  3. 修正 Windows 7 系列系統安裝2019 一月份安全性更新後的網芳問題
    2019/01/14 10:54

Blog 最新回應

  1. to QQQVICKI 手邊沒有 S........
    2019/01/16 17:20
  2. 我們公司拿掉KB4480970仍是不能連........
    2019/01/16 15:36
  3. test...
    2018/11/28 13:22

Keyword 關鍵字

Java 開放資料 OpenCV 3D立體 CUDA iFlyover OpenNI2 Pandas 資訊地圖 C++11 Pandas 3d print git ja<x>vascript NiTE2 Python OpenGL OpenNI Python 資料視覺化 開放資料 Boost Vulkan Kinect xml CubeX WebGL svn OpenMP OpenCL C++14

類別:技術相關 » 技術研究
文章發表|我要回應|RSS訂閱

OpenNI 2 的錯誤處理

在上一篇的《OpenNI 2 基本程式範例》裡,Heresy 基本上是先整理了一下,要使用 Visual Studio 來進行 OpenNI 2 的程式開發的話,要怎樣進專案的設定,另外也用一個最簡單的例子,來說明 OpenNI 2 的程式要怎麼寫。而這一篇,則是再繼續做補充,讓程式更完整。

在上一個範例裡面,Heresy 為了版面、以及簡化程式碼的關係,是假設程式執行都沒有問題,所以把所有錯誤的檢查都拿掉了。不過實際上,程式在執行的時候,其實都是應該要考慮到各種錯誤狀況的!而 OpenNI 2 也有提供一些簡單的介面,可以用來檢查程式執行時,有沒有錯誤。

首先,和 OpenNI 1.x 的時候,OpenNI 大部分的函式,都會回傳一個代表結果的值,讓開發者可以據此判斷該函式是否已正確執行;而在 OpenNI 2,這個回傳的結果,是一個叫做 openni::Status 的列舉型別。基本的使用狀況,大致上如下:

openni::Status eRes = openni::OpenNI::initialize();
if( eRes != openni::STATUS_OK )
{
std::cerr &lt;&lt; openni::OpenNI::getExtendedError()
&lt;&lt; std::endl;
return -1;
}

如果函式有正確執行的話,所得到的回傳值會是 openni::STATUS_OK;反過來說,只要回傳值不是 STATUS_OK, 就代表函式執行是有問題的。

而基本上 openni::Status 已經定義的一些常見的錯誤狀況,可以用來做進一步處理的判斷。不過如果是想要得到文字性的錯誤說明的話,也可以透過 openni::OpenNI::getExtendedErropr() 這個函式,來取得更完整的錯誤說明文字。不過要注意的是,他取得的會是最後一筆錯誤資訊,如果之後又有呼叫其他函式的話,可能會影響到它的內容。(不過他是 thread-safe 的)

而如果把之前的範例,全部都加上錯誤檢查的話,則會變成類似這樣子:

// STL Header
#include&#160;&lt;iostream&gt;

// 1. include OpenNI Header
#include&#160;&quot;OpenNI.h&quot;

// using namespace
using&#160;namespace std;
using&#160;namespace openni;

int main( int argc, char** argv )
{
// 2. initialize OpenNI
if( OpenNI::initialize() == STATUS_OK )
{
// 3. open a device
Device devAnyDevice;
if( devAnyDevice.open( ANY_DEVICE ) == STATUS_OK )
{
// 4. create depth stream
VideoStream streamDepth;
if( streamDepth.create( devAnyDevice, SENSOR_DEPTH ) == STATUS_OK )
{
if( streamDepth.start() == STATUS_OK )
{
// 5 main loop, continue read
VideoFrameRef frameDepth;
for( int i = 0; i &lt; 100; i )
{
// 5.1 get frame
if( streamDepth.readFrame( &amp;frameDepth ) == STATUS_OK )
{
// 5.2 get data array
const DepthPixel* pDepth = (const DepthPixel*)frameDepth.getData();

// 5.3 output the depth value of center point
int idx = frameDepth.getWidth()*(frameDepth.getHeight() 1)/2;
cout &lt;&lt; pDepth[idx] &lt;&lt; endl;
}
else
{
cerr &lt;&lt; &quot;Can not read frame\n&quot;;
cerr &lt;&lt; OpenNI::getExtendedError() &lt;&lt; endl;
}
}
}
else
{
cerr &lt;&lt; &quot;Can not start depth stream\n&quot;;
cerr &lt;&lt; OpenNI::getExtendedError() &lt;&lt; endl;
}

streamDepth.destroy();
}
else
{
cerr &lt;&lt; &quot;Can not create depth stream\n&quot;;
cerr &lt;&lt; OpenNI::getExtendedError() &lt;&lt; endl;
}

devAnyDevice.close();
}
else
{
cerr &lt;&lt; &quot;Can not open device\n&quot;;
cerr &lt;&lt; OpenNI::getExtendedError() &lt;&lt; endl;
}

// 7. shutdown
OpenNI::shutdown();
}
else
{
cerr &lt;&lt; &quot;OpenNI initialize error\n&quot;;
cerr &lt;&lt; OpenNI::getExtendedError() &lt;&lt; endl;
}

return 0;
}

這裡比較不一樣的是,Heresy 在前面有加上 using namespace openni;, 指定去使用 openni 這個 namespace,所以之後的程式,都可以把 namespace 省略掉;如此一來,程式寫起來會再簡短一點。

當然,上面的寫法也不是唯一的錯誤檢查的方法。像在官方範例「SimpleRead」裡面,採用的就是另一種程式風格的流程,有興趣的也可以看看。要採用哪種,基本上就是看人習慣了~只是另外也要提一下,理論上在出現錯誤時,main() 應該也要回傳非 0 的錯誤代碼的,Heresy 這邊沒有特別去處理這一塊就是了。

不過…既然都是 C 的 API 了,沒有採用 exception(參考)來做處理…Heresy 個人是覺得有點可惜啊…總覺得以各方面來說,OpenNI 的開發團隊,似乎對 C 不是很熟悉?雖然 OpenNI 1.x 和 OpenNI 2 都提供了 C 的 API,但是實際上,很多介面設計的方式,都還是用 C 的形式來做的…還是其實是有其他考量?所以甚至連陣列都是另外寫一個自己的版本(openni::Array),而沒有直接採用 STL 的版本(也沒有 iterator 可以用)…

張貼者:heresy於2012/12/26 10:36 上午有7則回應,瀏覽次數:1,947次
Jerry 於 2015/10/01 15:05 下午 回應:
您好:
我的系統是win7 64bit vs2010
OpenNI2安裝64bit , Microsoft SDK v1.6
(測試Microsoft SDK v1.6的範例有成功)
按照上面的範例開了一個C 的新專案
出現以下的錯誤,覺得很奇怪為什麼錯誤會出
在.h檔
明明.h是下載下來的
而且我安裝好之後執行OpenNI2資料夾內的Sample
的SimpleViewer
執行之後出現以下結果:
After initialization:
SimpleViewer: Couldn't start depth stream
SimpleViewer: Couldn't start color stream
SimpleViewer: No valid streams. exiting
是我安裝不完整嗎?


1>test101.cpp(3): warning C4627: '#include ': 尋找先行編譯標頭使用時略過
1> 新增指示詞到 'StdAfx.h' 或重建先行編譯標頭
1>c:\program files\openni2\include\OniCTypes.h(81): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'usbVendorId' 之前)
1>c:\program files\openni2\include\OniCTypes.h(81): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(81): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(82): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'usbProductId' 之前)
1>c:\program files\openni2\include\OniCTypes.h(82): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(82): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(101): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'timestamp' 之前)
1>c:\program files\openni2\include\OniCTypes.h(101): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(101): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(143): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'OniDepthPixel' 之前)
1>c:\program files\openni2\include\OniCTypes.h(143): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(143): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(153): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'OniGrayscale8Pixel' 之前)
1>c:\program files\openni2\include\OniCTypes.h(153): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCTypes.h(153): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>c:\program files\openni2\include\OniCAPI.h(193): error C2061: 語法錯誤 : 識別項 'OniDepthPixel'
1>C:\Program Files\OpenNI2\Include\OpenNI.h(385): error C2065: 'usbVendorId' : 未宣告的識別項
1>C:\Program Files\OpenNI2\Include\OpenNI.h(387): error C2065: 'usbProductId' : 未宣告的識別項
1>C:\Program Files\OpenNI2\Include\OpenNI.h(497): error C2146: 語法錯誤 : 遺漏 ';' (在識別項 'getTimestamp' 之前)
1>C:\Program Files\OpenNI2\Include\OpenNI.h(497): error C2433: 'openni::VideoFrameRef::uint64_t' : 'inline' 不允許使用在資料宣告上
1>C:\Program Files\OpenNI2\Include\OpenNI.h(497): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>C:\Program Files\OpenNI2\Include\OpenNI.h(498): error C4430: 遺漏型別規範 - 假設為 int。注意: C 不支援 default-int
1>C:\Program Files\OpenNI2\Include\OpenNI.h(500): warning C4183: 'getTimestamp': 遺漏傳回型別; 假設是傳回 'int' 的成員函式
1>C:\Program Files\OpenNI2\Include\OpenNI.h(499): error C2039: 'timestamp' : 不是 'OniFrame' 的成員
1> c:\program files\openni2\include\OniCTypes.h(96) : 請參閱 'OniFrame' 的宣告
1>C:\Program Files\OpenNI2\Include\OpenNI.h(2473): error C2660: 'oniCoordinateConverterDepthToColor' : 函式不使用 7 引數
Jerry 於 2015/10/01 15:25 下午 回應:
抱歉...我留言留錯地方了本來要留在"OpenNI 2 基本程式範例"這邊
不好意思洗版了
作者作者heresy 於 2015/10/01 15:47 下午 回應:
to Jerry

建議請先使用 NiViewer 試試看,能不能正常顯示。
另外,K4w SDK 建議更新到最後的 1.8 版
Jerry 於 2015/10/01 16:10 下午 回應:
heresy:

已經更新到k4w SDK已更新到1.8
NiViewer沒法正常顯示
顯示Depth Stream is off Color Stream is off
不曉得是哪裡出了問題
作者作者heresy 於 2015/10/01 17:07 下午 回應:
to Jerry

建議可以做的測試:
1. 重新開機
2. 請確認所有 Kinect 相關的程式都已關閉、再開啟 NiViewer 進行測試
Jerry 於 2015/10/01 17:16 下午 回應:
heresy:
會不會是下面這個問題?
網路上其他人的建議

UsbInterface=2改成UsbInterface=0
作者作者heresy 於 2015/10/02 15:42 下午 回應:
to Jerry

你可以試試看,但是個人覺得應該不會有影響。
因為這邊要改的檔案應該是 PS1080.ini,他是給 PrimeSense 的標準感應器(ASUS Xtion)用的,而不是給 Kinect 用的。

-- TOP --

我要回應
* 身份  訪客 (暱稱:)
 本篇文章作者 (帳號:密碼:)
* 內容      
很高興 悲傷 震驚 疑惑 大笑 發瘋 傷心
* 留言密碼 (請輸入下方圖片中去除前、後位數的數字,共五碼。)
說明 1. * 表示必填欄位。
2. 不支援HTML Tag。
   

-- TOP --

© Visualization and Interactive Media Laboratory of NCHC, 2007 - 2019, All Rights Reserved. Contact E-mail