検索
AND検索
OR検索
トップ
|
リロード
|
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
執筆/雑誌/SD/2009/03/仮想現実感・本文 をテンプレートにして作成
詳細は
入会方法
をご覧下さい。
メニュー
日本Androidの会とは?
入会方法
イベント
技術資料
ワーキンググループ
支部
リリース
Japan Android Report
リンク
FAQ
権利関係
プライバシーポリシー
Twitter
公式Youtubeチャンネル
NPOサイト
最新の10件
2023-11-13
ABC2023A-pr
リリース
2023-10-13
MenuBar
入会方法
2023-09-17
ワーキンググループ/香川支部
2023-09-07
林田官呂
2023-08-19
イベント/イベント予定表
2023-06-11
日本Androidの会とは?
2023-06-01
秋葉 楓
2022-11-07
スタッフ
edit
Total:0/Today:0
開始行:
[[執筆/雑誌/SD/2009/03]]
技術評論社さんのご厚意により、本文を公開いたします。~
[[「SoftwareDesign」2009年03月號>http://gihyo.jp/magazine...
*タイトル [#ta1d6b92]
Android + AR(拡張現実感) で広がる現実世界
*1)どんなもの? [#k9de9363]
***どんなアプリなの? [#zc71f223]
みなさん、「Augmented Reality:拡張現実感(以下、AR)」をご...
~
#ref(fig-1.jpg);
~
本節で作成するアプリでは、カメラで撮った画像を解析して、...
~
~
-コラム
本アプリは、ライブラリのとしての側面が強いため、改造し独...
***Androidアプリケーションとしては? [#sdcefc75]
リスト1に示すように、Androidパッケージ名は「jp.android_gr...
~
-カメラによる、リアル映像の取得
-Androidにおける、デバイスの利用方法
-ARライブラリによる、マーカーの検知と三次元位置・姿勢の...
-Androidにおける、外部ライブラリの使用方法
-3D(OpenGL/ES)による、3Dモデル・オブジェクトの描画・表示
-Android版OpenGL/ESの利用方法
~
のように構成されております。以後は、この順番にしたがって...
-リスト1
-jp.android_group.artoolkitパッケージ・・・本アプリのベ...
- NyARToolkitAndroidActivityクラス・・・本アプリの起動...
- ARToolkitDrawerクラス・・・ARToolkit処理のためのクラス
- ModelRenderer・・・GLSurfaceView#Rendererインタフェ...
-jp.android_group.artoolkit.hardwareパッケージ・・・各種...
- SocketCamera・・・Socketでカメラ画像を受信するカメラ...
- G1Camera・・・G1のカメラデバイスのラッパー実装
-jp.android_group.artoolkit.modelパッケージ・・・各種3D...
- Cube・・・AndroidのサンプルにあるCubeクラス
-jp.android_group.artoolkit.viewパッケージ・・・OpenGL/E...
- GLSurfaceView・・・OpenGL/ES処理のためのSurfaceView...
- GLBg・・・背景テクスチャを貼り付けるためのOpenGL/ES...
*2)カメラ画像を取得する [#z6ac800d]
***エミュレータ x ハードウェア x Socket [#c7e55424]
最初に、カメラ画像の取得を行います。しかし、Androidエミュ...
を紹介します。~
~
-※注1
Android Marketより、Dev 1 Phoneの発注が可能ですが、$499...
~
具体的には、母艦PCに接続したWebカメラの画像をSocket通信で...
~
-※注2
動作には、JMF(Java Media Framework)が必要です。
~
あれ?どこかで見たことがあるソースコードだと思いませんか...
~
-リスト2
public class WebcamBroadcaster {
// (略)
public void start() {
synchronized (lock) {
// JMFによりWebカメラデバイスを初期化する。
worker = new Worker();
worker.run();
}
}
private class Worker extends Thread {
public void run() {
ServerSocket ss;
ss = new ServerSocket(port);
while(true) {
Socket socket = ss.accept();
OutputStream out = socket.getOutputStream();
// JMFによりWebカメラデバイスから、画像...
for (int i = 0; i < data.length; i++) {
dout.writeInt(data[i]);
}
}
}
}
}
~
-リスト3
public class SocketCamera implements CameraIF {
// (略)
public void setPreviewCallback(PreviewCallback callback...
this.callback = callback;
}
private class CaptureThread extends Thread {
public void run() {
while (!mDone) {
Socket socket = new Socket();
socket.connect(IPAddress_and_Port, SOCKET_T...
InputStream in = socket.getInputStream();
// (略)
callback.onPreviewFrame(buf, null);
}
}
}
}
public interface PreviewCallback {
void onPreviewFrame(byte[] data, Camera camera);
};
***Camera x Callback x Bitmap [#uc8498e6]
カメラから画像データが取得できましたので、この画像データ...
ARToolkitDrawer#draw(byte[])メソッドでは、BitmapFactory#d...
~
-リスト4
public class NyARToolkitAndroidActivity extends Activity...
private ARToolkitDrawer arToolkit;
(略)
private final class JpegPreviewCallback implements P...
public void onPreviewFrame(byte [] jpegData, Came...
if(jpegData != null) {
arToolkit.draw(jpegData);
}
}
};
public class ARToolkitDrawer {
(略)
public void draw(byte[] data) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.l...
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pixels = new int[w * h];
byte[] buf = new byte[pixels.length * 3];
bitmap.getPixels(pixels, 0, w, 0, 0, w, h);
for (int i = 0; i < pixels.length; i++) {
int argb = pixels[i];
byte a = (byte) (argb & 0xFF000000 >> 24);
byte r = (byte) (argb & 0x00FF0000 >> 16);
byte g = (byte) (argb & 0x0000FF00 >> 8);
byte b = (byte) (argb & 0x000000FF);
buf[i * 3] = r;
buf[i * 3 + 1] = g;
buf[i * 3 + 2] = b;
}
(略)
}
}
-コラム:Androidでのデバイスの扱い
デバイスからカメラ画像を取得するためにxxxCallbackインタ...
ちなみに、この他に同じ役割をするものとして、xxxListener...
*3)ARToolkitを使う [#u9f06919]
***どう実現する? [#h389c111]
本アプリでは、ARを実現するためにARToolkit(コラム参照)のAn...
#ref(fig-2.jpg);
-コラム:ARToolkitについて
ARToolkitは、ARを実現するためのライブラリです。加藤博一...
ARToolkit公式サイト:http://www.hitl.washington.edu/arto...
NyARToolkitプロジェクトは、いろいろな言語へのARToolkitの...
***マーカー x 初期化 x 検知 [#h323e90d]
NyARToolkitの設定や初期化は、リスト5のARToolkitDrawerクラ...
初期化は、画像の縦横サイズが必要なため、リスト5のARToolki...
次は、ARToolkitの処理を行い、三次元位置と姿勢を取得します...
~
-リスト5
public class ARToolkitDrawer {
private GLNyARSingleDetectMarker nya = null;
private NyARRaster_RGB raster = new NyARRaster_RGB();
private GLNyARParam ar_param = new GLNyARParam();
private NyARCode ar_code = new NyARCode(16, 16);
public ARToolkitDrawer(InputStream camePara, InputStrea...
this.camePara = camePara;
this.patt = patt;
this.mRenderer = mRenderer;
}
private void createNyARTool(int w, int h) {
// NyARToolkit setting.
ar_param.loadFromARFile(camePara);
ar_param.changeSize(w, h);
ar_code.loadFromARFile(patt);
nya = new GLNyARSingleDetectMarker(ar_param, ar_code, ...
nya.setContinueMode(true);
}
(略)
}
~
-リスト6
public class ARToolkitDrawer {
public void draw(byte[] data) {
// (略)
NyARRaster_RGB.wrap(raster, buf, w, h);
boolean is_marker_exist = nya.detectMarkerLite(raster,...
if (is_marker_exist) {
float[] cameraRHf = ar_param.getCameraFrustumRHf();
nya.getCameraViewRH(resultf);
// (略)
}
}
}
*4)3Dモデルを表示する [#e173e02f]
***OpenGL/ES for Android 事始め [#c3cf31cf]
Androidでは、3DライブラリとしてOpenGL/ESの1.0と1.1の一部...
~
-全てJavaで実装
-API体系はJSR239相当
-OpenGL/ES の 1.0 +1.1の一部
-微妙に引数の数が違う関数がある
-EGLが見える/見えない
-バッファはnio扱い
-SurfaceViewクラスでの実装となる
~
といったところです。詳細な情報は、日本Androidの会2008/12...
-※注3
http://www.android-group.jp/index.php?%CA%D9%B6%AF%B2%F1...
***SurfaceView x Thread x Renderer [#j291ec76]
AndroidでOpenGL/ESを使用するには、SurfaceViewクラスの利用...
まず、初期化は、リスト7のGLSurfaceView#init()メソッドで行...
~
-※注4
Callbackについては、「コラム:Androidでのデバイスの扱い...
~
しかし、これでは、肝心の3Dオブジェクトがありません。そこ...
(※注5)画面に変更があってすぐ書き換えるのではなく、ある程...
さらに、GLSurfaceViewクラスの内部で定義されているRenderer...
~
-※注6
正確には、その次に呼ばれているEglHelper#swap()が契機です。
~
-リスト7
public class GLSurfaceView extends SurfaceView implement...
private void init() {
// Install a SurfaceHolder.Callback so we get no...
// underlying surface is created and destroyed
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
public void setRenderer(Renderer renderer) {
mGLThread = new GLThread(renderer);
mGLThread.start();
}
// (略)
}
~
-リスト8
public class GLSurfaceView extends SurfaceView implement...
// (略)
class GLThread extends Thread {
public void run() {
guardedRun();
}
private void guardedRun() throws InterruptedExce...
while (true) {
// (略)
if ((w > 0) && (h > 0)) {
mRenderer.drawFrame(gl);
mEglHelper.swap();
}
}
}
}
}
これで、3Dを使う準備が出来ました。最後に、背景となる画像...
ここで、初登場となるリスト9のModelRendererクラスがありま...
つづいて、マーカーが発見された場合、ModelRenderer#objectP...
~
-リスト9
public class ARToolkitDrawer {
ModelRenderer mRenderer;
public void draw(byte[] data) {
// (略)
mRenderer.setBgBitmap(bitmap);
// (略)
boolean is_marker_exist = nya.detectMarkerLite(raster,...
if (is_marker_exist) {
float[] cameraRHf = ar_param.getCameraFrustumRHf();
nya.getCameraViewRH(resultf);
mRenderer.objectPointChanged(resultf, cameraRHf);
} else {
mRenderer.objectClear();
}
}
}
*5)終わりに [#zc7b12bb]
お疲れ様でした。いかがでしたでしょうか?非常に駆け足とな...
*執筆者 [#wc246dde]
-日本Androidの会 事務局長 & グロースエクスパートナーズ株...
-株式会社ケイブ 山崎淳
終了行:
[[執筆/雑誌/SD/2009/03]]
技術評論社さんのご厚意により、本文を公開いたします。~
[[「SoftwareDesign」2009年03月號>http://gihyo.jp/magazine...
*タイトル [#ta1d6b92]
Android + AR(拡張現実感) で広がる現実世界
*1)どんなもの? [#k9de9363]
***どんなアプリなの? [#zc71f223]
みなさん、「Augmented Reality:拡張現実感(以下、AR)」をご...
~
#ref(fig-1.jpg);
~
本節で作成するアプリでは、カメラで撮った画像を解析して、...
~
~
-コラム
本アプリは、ライブラリのとしての側面が強いため、改造し独...
***Androidアプリケーションとしては? [#sdcefc75]
リスト1に示すように、Androidパッケージ名は「jp.android_gr...
~
-カメラによる、リアル映像の取得
-Androidにおける、デバイスの利用方法
-ARライブラリによる、マーカーの検知と三次元位置・姿勢の...
-Androidにおける、外部ライブラリの使用方法
-3D(OpenGL/ES)による、3Dモデル・オブジェクトの描画・表示
-Android版OpenGL/ESの利用方法
~
のように構成されております。以後は、この順番にしたがって...
-リスト1
-jp.android_group.artoolkitパッケージ・・・本アプリのベ...
- NyARToolkitAndroidActivityクラス・・・本アプリの起動...
- ARToolkitDrawerクラス・・・ARToolkit処理のためのクラス
- ModelRenderer・・・GLSurfaceView#Rendererインタフェ...
-jp.android_group.artoolkit.hardwareパッケージ・・・各種...
- SocketCamera・・・Socketでカメラ画像を受信するカメラ...
- G1Camera・・・G1のカメラデバイスのラッパー実装
-jp.android_group.artoolkit.modelパッケージ・・・各種3D...
- Cube・・・AndroidのサンプルにあるCubeクラス
-jp.android_group.artoolkit.viewパッケージ・・・OpenGL/E...
- GLSurfaceView・・・OpenGL/ES処理のためのSurfaceView...
- GLBg・・・背景テクスチャを貼り付けるためのOpenGL/ES...
*2)カメラ画像を取得する [#z6ac800d]
***エミュレータ x ハードウェア x Socket [#c7e55424]
最初に、カメラ画像の取得を行います。しかし、Androidエミュ...
を紹介します。~
~
-※注1
Android Marketより、Dev 1 Phoneの発注が可能ですが、$499...
~
具体的には、母艦PCに接続したWebカメラの画像をSocket通信で...
~
-※注2
動作には、JMF(Java Media Framework)が必要です。
~
あれ?どこかで見たことがあるソースコードだと思いませんか...
~
-リスト2
public class WebcamBroadcaster {
// (略)
public void start() {
synchronized (lock) {
// JMFによりWebカメラデバイスを初期化する。
worker = new Worker();
worker.run();
}
}
private class Worker extends Thread {
public void run() {
ServerSocket ss;
ss = new ServerSocket(port);
while(true) {
Socket socket = ss.accept();
OutputStream out = socket.getOutputStream();
// JMFによりWebカメラデバイスから、画像...
for (int i = 0; i < data.length; i++) {
dout.writeInt(data[i]);
}
}
}
}
}
~
-リスト3
public class SocketCamera implements CameraIF {
// (略)
public void setPreviewCallback(PreviewCallback callback...
this.callback = callback;
}
private class CaptureThread extends Thread {
public void run() {
while (!mDone) {
Socket socket = new Socket();
socket.connect(IPAddress_and_Port, SOCKET_T...
InputStream in = socket.getInputStream();
// (略)
callback.onPreviewFrame(buf, null);
}
}
}
}
public interface PreviewCallback {
void onPreviewFrame(byte[] data, Camera camera);
};
***Camera x Callback x Bitmap [#uc8498e6]
カメラから画像データが取得できましたので、この画像データ...
ARToolkitDrawer#draw(byte[])メソッドでは、BitmapFactory#d...
~
-リスト4
public class NyARToolkitAndroidActivity extends Activity...
private ARToolkitDrawer arToolkit;
(略)
private final class JpegPreviewCallback implements P...
public void onPreviewFrame(byte [] jpegData, Came...
if(jpegData != null) {
arToolkit.draw(jpegData);
}
}
};
public class ARToolkitDrawer {
(略)
public void draw(byte[] data) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.l...
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pixels = new int[w * h];
byte[] buf = new byte[pixels.length * 3];
bitmap.getPixels(pixels, 0, w, 0, 0, w, h);
for (int i = 0; i < pixels.length; i++) {
int argb = pixels[i];
byte a = (byte) (argb & 0xFF000000 >> 24);
byte r = (byte) (argb & 0x00FF0000 >> 16);
byte g = (byte) (argb & 0x0000FF00 >> 8);
byte b = (byte) (argb & 0x000000FF);
buf[i * 3] = r;
buf[i * 3 + 1] = g;
buf[i * 3 + 2] = b;
}
(略)
}
}
-コラム:Androidでのデバイスの扱い
デバイスからカメラ画像を取得するためにxxxCallbackインタ...
ちなみに、この他に同じ役割をするものとして、xxxListener...
*3)ARToolkitを使う [#u9f06919]
***どう実現する? [#h389c111]
本アプリでは、ARを実現するためにARToolkit(コラム参照)のAn...
#ref(fig-2.jpg);
-コラム:ARToolkitについて
ARToolkitは、ARを実現するためのライブラリです。加藤博一...
ARToolkit公式サイト:http://www.hitl.washington.edu/arto...
NyARToolkitプロジェクトは、いろいろな言語へのARToolkitの...
***マーカー x 初期化 x 検知 [#h323e90d]
NyARToolkitの設定や初期化は、リスト5のARToolkitDrawerクラ...
初期化は、画像の縦横サイズが必要なため、リスト5のARToolki...
次は、ARToolkitの処理を行い、三次元位置と姿勢を取得します...
~
-リスト5
public class ARToolkitDrawer {
private GLNyARSingleDetectMarker nya = null;
private NyARRaster_RGB raster = new NyARRaster_RGB();
private GLNyARParam ar_param = new GLNyARParam();
private NyARCode ar_code = new NyARCode(16, 16);
public ARToolkitDrawer(InputStream camePara, InputStrea...
this.camePara = camePara;
this.patt = patt;
this.mRenderer = mRenderer;
}
private void createNyARTool(int w, int h) {
// NyARToolkit setting.
ar_param.loadFromARFile(camePara);
ar_param.changeSize(w, h);
ar_code.loadFromARFile(patt);
nya = new GLNyARSingleDetectMarker(ar_param, ar_code, ...
nya.setContinueMode(true);
}
(略)
}
~
-リスト6
public class ARToolkitDrawer {
public void draw(byte[] data) {
// (略)
NyARRaster_RGB.wrap(raster, buf, w, h);
boolean is_marker_exist = nya.detectMarkerLite(raster,...
if (is_marker_exist) {
float[] cameraRHf = ar_param.getCameraFrustumRHf();
nya.getCameraViewRH(resultf);
// (略)
}
}
}
*4)3Dモデルを表示する [#e173e02f]
***OpenGL/ES for Android 事始め [#c3cf31cf]
Androidでは、3DライブラリとしてOpenGL/ESの1.0と1.1の一部...
~
-全てJavaで実装
-API体系はJSR239相当
-OpenGL/ES の 1.0 +1.1の一部
-微妙に引数の数が違う関数がある
-EGLが見える/見えない
-バッファはnio扱い
-SurfaceViewクラスでの実装となる
~
といったところです。詳細な情報は、日本Androidの会2008/12...
-※注3
http://www.android-group.jp/index.php?%CA%D9%B6%AF%B2%F1...
***SurfaceView x Thread x Renderer [#j291ec76]
AndroidでOpenGL/ESを使用するには、SurfaceViewクラスの利用...
まず、初期化は、リスト7のGLSurfaceView#init()メソッドで行...
~
-※注4
Callbackについては、「コラム:Androidでのデバイスの扱い...
~
しかし、これでは、肝心の3Dオブジェクトがありません。そこ...
(※注5)画面に変更があってすぐ書き換えるのではなく、ある程...
さらに、GLSurfaceViewクラスの内部で定義されているRenderer...
~
-※注6
正確には、その次に呼ばれているEglHelper#swap()が契機です。
~
-リスト7
public class GLSurfaceView extends SurfaceView implement...
private void init() {
// Install a SurfaceHolder.Callback so we get no...
// underlying surface is created and destroyed
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
public void setRenderer(Renderer renderer) {
mGLThread = new GLThread(renderer);
mGLThread.start();
}
// (略)
}
~
-リスト8
public class GLSurfaceView extends SurfaceView implement...
// (略)
class GLThread extends Thread {
public void run() {
guardedRun();
}
private void guardedRun() throws InterruptedExce...
while (true) {
// (略)
if ((w > 0) && (h > 0)) {
mRenderer.drawFrame(gl);
mEglHelper.swap();
}
}
}
}
}
これで、3Dを使う準備が出来ました。最後に、背景となる画像...
ここで、初登場となるリスト9のModelRendererクラスがありま...
つづいて、マーカーが発見された場合、ModelRenderer#objectP...
~
-リスト9
public class ARToolkitDrawer {
ModelRenderer mRenderer;
public void draw(byte[] data) {
// (略)
mRenderer.setBgBitmap(bitmap);
// (略)
boolean is_marker_exist = nya.detectMarkerLite(raster,...
if (is_marker_exist) {
float[] cameraRHf = ar_param.getCameraFrustumRHf();
nya.getCameraViewRH(resultf);
mRenderer.objectPointChanged(resultf, cameraRHf);
} else {
mRenderer.objectClear();
}
}
}
*5)終わりに [#zc7b12bb]
お疲れ様でした。いかがでしたでしょうか?非常に駆け足とな...
*執筆者 [#wc246dde]
-日本Androidの会 事務局長 & グロースエクスパートナーズ株...
-株式会社ケイブ 山崎淳
ページ名: