NyARToolKit
NyARToolKit for Android
Section 14 AR描画部分のソースコード説明
サンプルソースのAR描画(ARToolkitDrawer.java)解説を行っていきます。
暫定版
この記事は暫定版です。順次更新されます。 この表示が消えるまで突っ込み禁止。
コンストラクタ(初期化)
カメラ出力、マーカーサイズ、マーカーパターン、表示格納領域を指定します。
/**
* 初期化処理
* マーカーパターン、カメラパラメータはここで読み込む
*/
private void initialization(InputStream camePara, int[] width, ArrayList<InputStream> patt) {
mNumPatt = patt.size();
marker_width = new double[mNumPatt];
ar_code = new NyARCode[mNumPatt];
try {
for (int i = 0; i < mNumPatt; i++) {
// マーカーの幅
marker_width[i] = width[i];
// マーカーの分割数
ar_code[i] = new NyARCode(16, 16);
ar_code[i].loadARPatt(patt.get(i));
}
ar_param = new NyARParam();
ar_param.loadARParam(camePara);
} catch (Exception e) {
Log.e("nyar", "resource loading failed", e);
}
}
NyARCodeはARToolKitのマーカーパターン1個のデータを格納します。 引数は作成するマーカパターンの横解像度,作成するマーカパターンの縦解像度です。
decodeYUV420SP(YUV→RGB)
カメラ画像はYUVフォーマットで取得されるため、RGB形式に変換してからARの認識処理に渡しています。 ここでは「jni」の方で処理されているため、詳細はjni.yuv420sp2rgb.yuv420sp2rgb.cを参照してください。
draw:メイン描画処理
//ARメイン処理
public void draw(byte[] data) {
if(data == null) {
Log.d("AR draw", "data= null");
return;
}
Log.d("AR draw", "data.length= " + data.length);
//スクリーンサイズ指定
int width = 320;
int height = 240;
// RGB格納用
byte[] buf = new byte[width * height * 3];
// assume YUV420SP
long time1 = SystemClock.uptimeMillis();
//YUV420からRGB24変換
decodeYUV420SP(buf, data, width, height, 1);
long time2 = SystemClock.uptimeMillis();
Log.d("ARToolkitDrawer", "RGB decode time: " + (time2 - time1) + "ms");
float[][] resultf = new float[MARKER_MAX][16];
int found_markers;
int ar_code_index[] = new int[MARKER_MAX];
//NyARToolKitの初期化 - カメラパラメータの読み込み
createNyARTool(width, height);
// マーカー検出
try {
Log.d("AR draw", "Marker detection.");
raster = new NyARRgbRaster_RGB(width, height);
raster.wrapBuffer(buf);
found_markers = nya.detectMarkerLite(raster, 100);
} catch (NyARException e) {
Log.e("AR draw", "marker detection failed", e);
return;
}
boolean isDetect = false;
// マーカーが検出された場合、描画
if (found_markers > 0) {
Log.d("AR draw", "!!!!!!!!!!!exist marker." + found_markers + "!!!!!!!!!!!");
// プロジェクションをGL用に変換
float[] cameraRHf = new float[16];
toCameraFrustumRHf(ar_param, cameraRHf);
if (found_markers > MARKER_MAX)
found_markers = MARKER_MAX;
for (int i = 0; i < found_markers; i++) {
//マーカーの一致率で 60% より小さい場合は認識していないと半定する。一致率は 0.0 < n < 1.0 の間
if (nya.getConfidence(i) < 0.60f)
continue;
try {
ar_code_index[i] = nya.getARCodeIndex(i);
NyARTransMatResult transmat_result = ar_transmat_result;
nya.getTransmationMatrix(i, transmat_result);
//OpenGLのModelView行列へ変換
toCameraViewRHf(transmat_result, resultf[i]);
isDetect = true;
} catch (NyARException e) {
Log.e("AR draw", "getCameraViewRH failed", e);
return;
}
}
//検出したマーカーの上に3Dモデル再描画
mRenderer.objectPointChanged(found_markers, ar_code_index, resultf, cameraRHf);
} else {
Log.d("AR draw", "not exist marker.");
mRenderer.objectClear();
}
// モデルデータなどに音をつける場合に使用
if (isDetect) {
if (mMediaPlayer != null) {
if (!mMediaPlayer.isPlaying())
mMediaPlayer.start();
}
}
else {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying())
mMediaPlayer.pause();
}
}
}
drawではマーカーの認識、描画等を行っています。 まずカメラ画像をYUV420→RGB24に変換を行い、変換後の画像をARToolkitに渡します。 ARToolkitに渡された画像からマーカーを認識し、マーカーの座標を取得します。 マーカーの座標に3Dモデルを出力するように再描画をかけ表示を行っています。
とても簡単なソースコード解説はこれで終了になります。