.jpg)
ゲーム
イベント
マガジン
技術ブログ
AWS では、データと AI を活用したイノベーションの推進を支援するため、「 AWS Data & AI イノベーションフォーラム:顧客成功事例から学ぶデータ活用の最前線 」というイベントを4/9,10に開催いたします。本記事では、4/10 の DAY 2 (Database 編) の詳細についてご案内します。 はじめに DAY 2 の見どころは、昨年 5 月に一般提供を開始した Amazon Aurora DSQL について、本番環境で使用中のお客様や検証したお客様をお呼びして、リアルな声をお届けするセッションです。 お客様の経験や課題解決のプロセスを知ることで、皆様のデータベース戦略にも活かしていただけます。 ぜひ会場でご参加ください。 イベント概要 本イベントは 2 日間にわたって開催され、AWS Data & AI 戦略の全体像から、実際のお客様事例まで幅広くご紹介します。 DAY 1 : AIML 、Analytics、Storage (別途お申し込みが必要です) DAY 2 : Database ※本記事でご紹介 DAY 2 では、AWS Director の Mehul Y. Shah による商用データベースの AWS 戦略についてのキーノートセッションから始まり、 DSQL を活用した次世代 DR 戦略の検討している東京海上日動システムズ様のセッション 、 DSQL を本番環境で実際に採用している Japan Digital Design 様による本番導入事例 、 本番環境を想定して DSQL のパフォーマンス検証を実施した Happy Elements 様のセッション 、そして AWS による RDS / Aurora や NoSQL 採用事例などを予定しています。 ※ 1 セッションからでもご参加いただけます。 ご興味のあるセッションのみの参加も歓迎いたします。 開催情報(Day 2) 項目 詳細 開催日時 2026 年 4 月 10 日 9:30 – 17:00 (日本時間) 開催場所 〒 141-0021 東京都品川区上大崎 3 丁目 1-1 目黒セントラルスクエア 17F AWS Startup Loft Tokyo 開催形式 オフライン (会場参加) 参加費 無料 定員 限定人数 (定員になり次第、受付を終了いたします) 申込方法 イベント申込ページ よりお申し込みください ※本イベントは定員に限りがございます。お早めにお申し込みください。 ※ DAY 1 (AIML 、Analytics 、Storage 編) の詳細・お申し込みは こちら からご確認ください。 プログラム詳細 時間 セッションタイトル 概要 登壇者 カテゴリ 09:30 – 09:35 Opening – – – 09:35 – 10:35 Keynote 「商用データベースの re:Invent : AWS が顧客起点で実現するデータイノベーション」 AWS が顧客の課題から出発する「Working Backwards」のアプローチを通じて、Amazon RDS をはじめとする商用データベースのイノベーションをどのように推進しているのかをご紹介します。re:Invent で発表された最新アップデート、パフォーマンス・スケーラビリティ・運用効率の向上、レガシーデータベースの移行からクラウドネイティブかつ AI 活用を見据えたデータ基盤の構築まで、厳選した事例とともにご紹介します。企業がコスト削減やリスク低減にとどまらず、商用データベースを戦略的資産として活用し、ビジネスイノベーションを加速している事例をご理解いただけます。 Mehul Y. Shah (Director for Amazon RDS and Oracle Database@AWS) AWS 戦略 10:45 – 12:00 【お客様登壇】 「DR 戦略の進化~ Amazon Aurora DSQL がもたらす新たな可能性と実践への第一歩~」 前半では、AWS より Aurora DSQL のアーキテクチャと主要な特徴を解説します。後半では、東京海上日動システムズ株式会社様より、既存システムの DR 構成における課題と、DSQL の Active-Active 構成がもたらす DR 戦略の変革の可能性についてお話しいただきます。DSQL 活用の検討段階で見えてきた課題にも触れていただくほか、AWS を戦略的に採用する判断基準についてもご共有いただきます。 山下 裕記 様 (東京海上日動システムズ株式会社 戦略企画部長) 小野 卓人 (AWS 金融ソリューション本部 シニアソリューションアーキテクト) DSQL 検討事例 12:00 – 13:00 昼食休憩 13:00 – 14:00 【お客様登壇】 「Amazon Aurora DSQL の本番導入事例のご紹介」 – 佐藤 慎 様 (Japan Digital Design 株式会社) DSQL 本番採用事例 14:15 – 15:15 【お客様登壇】 「実プロダクトで検証する Aurora DSQL の可能性と制約」 Happy Elements では、運用中のゲームタイトルの実プロダクトを使い、Aurora DSQL のパフォーマンス検証を行いました。検証から見えた Aurora DSQL の性能特性、楽観的同時実行制御や ALTER TABLE 制限などの制約、そしてコスト比較の結果を具体的な数値とともに余すことなく共有します。 長谷川 一輝 様 (Happy Elements 株式会社 チーフエンジニア インフラグループ グループリーダー) DSQL 検証結果 15:30 – 16:45 「AWS Database サービス最新顧客事例集」 AWS は、目的に応じた多様なデータベースサービスを提供しており、お客様のビジネス要件に最適なソリューションを選択いただけます。本セッションでは、実際のお客様事例を通じてデータベース採用の実践的なアプローチをご紹介します。オンプレミスや商用データベースから Amazon RDS / Aurora への移行事例、および NoSQL の効果的な採用事例を通じて、運用負荷削減、性能向上、コスト最適化を実現した事例についてご紹介します。 内山 義夫 (AWS) RDS/Aurora /NoSQL 事例 16:45 – 17:00 Closing こんな方におすすめ 本イベントは、特に以下のような方におすすめです: DSQL に興味があり、実際の本番・検証事例から学びたい方 DSQL の導入を検討されている方 データベースの移行やモダナイゼーションを検討されている方 データベース運用の効率化やコスト最適化を目指している方 他社のリアルな導入経験から具体的なヒントを得たい方 まとめ AWS Data & AI イノベーションフォーラム DAY 2 (Database 編) では、最新データベース戦略の解説から、実際のお客様による DSQL やその他データベースの移行事例まで、データベースに関する幅広い知見を得ることができます。 特に、DSQL について、お客様のリアルな声を直接お聞きいただける場となっております 。定員に限りがございますので、ぜひお早めにお申し込みください。 皆様のご参加を心よりお待ちしております。 今すぐ申し込む
みなさん、こんにちは。ソリューションアーキテクトの戸塚です。今週も 週刊AWS をお届けします。 だんだんと春めいてきて、花粉症に悩まされている方も多いのではないでしょうか。私はというと、今年はなぜか症状がほとんど出ず、久しぶりに快適に仕事ができています。 NRF 2026 で注目されたリテール AI の最新動向を扱う流通・小売・消費財むけイベントを 4月20日 に開催します。 「リテールの現場では「AIエージェントが“主”、人間が“従”」に AWSジャパン・五十嵐氏に聞く小売業界におけるマルチエージェントの台頭」 こちらの記事 をご参照いただき、AWS メンバーへ気軽にお声がけください。 それでは、先週の主なアップデートについて振り返っていきましょう。 2026年3月23日週の主要なアップデート 3/25(水) Amazon Bedrock AgentCore Runtime が永続的なエージェントファイルシステム状態のためのマネージドセッションストレージをサポート開始 (プレビュー) Amazon Bedrock AgentCore Runtime で、エージェントのファイルシステム状態を永続化できる機能がプレビュー開始されました。これまで AI エージェントがコードを書いたりパッケージをインストールしても、セッション終了時に全て失われていました。新機能により、エージェントが作成したファイルやインストールしたパッケージが自動的に保存され、次回のセッションでも継続して作業できるようになります。最大 1GB まで、14 日間データを保持します。詳細は こちらのドキュメントをご参照ください。 Amazon SageMaker HyperPod が Slurm オーケストレーションクラスターの継続プロビジョニングをサポート Amazon SageMaker HyperPod の Slurm 環境で連続プロビジョニング機能が利用可能になりました。従来は一部のインスタンスグループでプロビジョニングが失敗すると、クラスター全体の作成や拡張が失敗してロールバックされていました。今回のアップデートにより、利用可能なインスタンスで即座に AI/ML トレーニングを開始でき、バックグラウンドで残りの容量を自動的にプロビジョニングします。失敗したノードは非同期で再試行され、複数のインスタンスグループでの同時スケーリングも可能です。CreateCluster API で NodeProvisioningMode を Continuous に設定することで有効化できます。詳細は こちらのドキュメントをご参照ください。 P6-B300 と Slurm 25.11 をサポートした AWS ParallelCluster 3.15 AWS ParallelCluster 3.15 が一般提供開始となり、最新の NVIDIA Blackwell GPU を搭載した P6-B300 インスタンスと Slurm 25.11 をサポートしました。これにより AI/ML や高性能コンピューティング (HPC) ワークロードをより高性能な環境で実行できるようになります。EFA ネットワーク設定の改善や大規模クラスターでの密結合ワークロードの性能向上も実現し、科学技術計算がより効率的に処理できます。詳細は こちらのリリースノートをご参照ください。 AWS Transfer Family Applicability Statement 2 (AS2) が MDN の非同期受信をサポート AWS Transfer Family の AS2 で、非同期での MDN (Message Disposition Notifications) 受信がサポートされました。従来は同期のみでしたが、取引先の処理時間やネットワーク遅延に関係なく AS2 ワークフローを移行できます。ヘルスケアや製造業などでパートナーとの安全なデータ交換が可能になります。詳細は こちらのドキュメントをご参照ください。 Amazon SageMaker AI が 12 の追加モデルに対してサーバーレス強化学習ファインチューニングをサポート Amazon SageMaker AI で 12 の新しいモデルに対してサーバーレス強化学習ファインチューニングが利用可能になりました。これまではインフラの準備や管理が必要でしたが、今回のアップデートにより Qwen や DeepSeek シリーズなどの最新モデルを手軽にカスタマイズできます。特にコード生成や数学的推論など、従来の教師あり学習では難しかった複雑なタスクに対応可能で、従量課金制のため小規模な実験からでも始められます。バージニア北部、オレゴン、東京、アイルランドリージョンで提供中です。 Amazon Aurora PostgreSQL が数秒でのデータベース作成と接続をサポート Amazon Aurora PostgreSQL で Express Configuration という新機能が登場し、サーバーレスデータベースを数秒で作成・接続できるようになりました。従来は VPC やネットワーク設定に時間がかかっていましたが、事前設定済みの構成により初期セットアップが大幅に高速化されています。インターネットアクセスゲートウェイが自動で設定され、 VPN や AWS Direct Connect なしで開発ツールから直接接続可能です。また IAM 認証がデフォルトで有効化されるため、パスワード不要でセキュアにアクセスできます。 AWS Free Tier でも利用可能なので、 PostgreSQL を手軽に試したい開発者には最適です。詳細は こちらの Blog 記事をご参照ください。 Amazon Aurora PostgreSQL が AWS 無料利用枠で利用可能になりました Amazon Aurora PostgreSQL が AWS 無料枠で利用可能になりました。新規ユーザーはサインアップ時に 100 ドルのクレジットを取得でき、追加で 100 ドルのクレジットも獲得できます。従来は有料プランでしか利用できなかった高性能な PostgreSQL データベースを、無料で試すことができるようになったのが大きなメリットです。express configuration を使えば数秒でデータベースを作成・クエリ実行が可能で、学習コストを大幅に削減できます。詳細は こちらをご参照ください。 Amazon Route 53 Profiles がリソースと VPC 関連付けに対する詳細な IAM 権限をサポート Amazon Route 53 Profiles で細かい IAM 権限設定が可能になりました。これまでは Profile 全体への権限管理でしたが、今回のアップデートでプライベートホストゾーンや DNS Firewall ルールなど、特定のリソースタイプごとに権限を制御できます。例えば、特定の VPC への関連付け操作のみを許可したり、特定のドメイン名のルールだけ編集権限を与えるといった細かな権限設定が実現できます。組織内で DNS 管理の責任を分散させつつ、セキュリティを保てるため大規模な環境での運用が格段に楽になります。詳細は こちらのドキュメントをご参照ください。 3/26(木) AWS Advanced JDBC Wrapper が Valkey による自動クエリキャッシュをサポート AWS Advanced JDBC Wrapper が Valkey を使った自動クエリキャッシュ機能をサポートしました。従来は JDBC クエリの結果をキャッシュするために、開発者が手動でコードを書く必要がありましたが、今回のアップデートで数ステップの簡単な設定だけで自動化できるようになりました。Aurora や RDS の PostgreSQL、MySQL、MariaDB データベースのクエリ結果を Amazon ElastiCache for Valkey に保存し、頻繁にアクセスするデータの読み取り遅延を削減できます。これによりデータベースへの読み取り回数が減り、パフォーマンス向上とコスト削減を実現できます。Hibernate や Spring Data といった人気フレームワークにも対応しているため、既存のアプリケーションへの導入も簡単です。詳細は こちらのドキュメントをご参照ください。 AWS AppConfig がフィーチャーフラグロールアウト中の拡張ターゲティングを追加 AWS AppConfig にフィーチャーフラグの段階的ロールアウト中に特定のユーザーやセグメントをターゲットできる新機能が追加されました。従来は段階的デプロイメント中に特定のユーザーグループだけに絞って配信することが難しかったのですが、今回のアップデートにより個別の ユーザー ID やセグメント単位での細かい制御が可能になります。これにより新機能のリリース時のリスクを大幅に削減でき、A/B テストや段階的な機能展開がより安全に実施できるようになります。詳細は こちらのドキュメントをご参照ください。 Writer の Palmyra Vision 7B が Amazon Bedrock で利用可能に Amazon Bedrock で Writer の Palmyra Vision 7B モデルが利用開始されました。このモデルは画像を理解してテキストを生成する AI で、文書分析やチャート解釈、手書き文字の抽出などが可能です。これまで画像内容を理解するには別のツールが必要でしたが、Bedrock 上で簡単に画像理解機能を組み込めるようになります。詳細は こちらのドキュメントをご参照ください。 3/27(金) Amazon GameLift Servers が次世代 EC2 インスタンスファミリーでインスタンスサポートを拡張 Amazon GameLift Servers が EC2 第 5 ~ 8 世代インスタンスに対応しました。これまでより新しい世代の EC2 インスタンスを利用できるようになり、ゲームサーバーのホスティングにおいて価格性能比の向上と効率性が実現されます。汎用 (M シリーズ)、コンピューティング最適化 (C シリーズ)、メモリ最適化 (R シリーズ) の 3 つのインスタンスファミリーから、ゲームの負荷特性に応じて最適な選択が可能です。詳細は こちらのドキュメントをご参照ください。 AWS Management Console でサービスとリージョンの表示を制御する設定をサポート開始 AWS Management Console で、表示するサービスとリージョンを制御できる設定が一般提供開始されました。これまで全てのサービスやリージョンが表示されていましたが、必要なもののみを表示することでナビゲーションが簡素化され、チームメンバーが利用可能なリソースを素早く特定できます。アカウント設定の Unified Settings から設定でき、CLI や SDK からのプログラム設定にも対応しています。詳細は こちらのドキュメント をご参照ください。 AWS Lambda が Lambda マネージドインスタンスで最大 32 GB のメモリと 16 vCPU をサポート AWS Lambda Managed Instances で最大 32 GB のメモリと 16 vCPU がサポートされるようになりました。これまでは 10 GB メモリと約 6 vCPU が上限でしたが、大規模なデータ処理やメディア変換などの計算集約的なワークロードも実行可能になります。メモリ対 vCPU の比率 (2:1、4:1、8:1) も選択でき、ワークロードの特性に合わせて最適なリソース配分を設定できます。詳細は こちらのドキュメントをご参照ください。 Amazon CloudWatch Logs が Infrequent Access 取り込みクラスでデータ保護、OpenSearch PPL、OpenSearch SQL をサポート開始 Amazon CloudWatch Logs の Infrequent Access (IA) クラスで、データ保護機能と OpenSearch PPL / SQL クエリがサポートされました。従来は Logs Insights のみでしたが、今回のアップデートにより SQL ベースの高度な分析が可能になります。また、ログ内の機密情報を自動検出・マスキングできるため、セキュリティ要件を満たしながらコスト効率的にログを統合できます。詳細は こちらのドキュメントをご参照ください。 今週はアップデートの内容に少し偏りがあり、月・火は落ち着いていた一方で、週の後半に多くの更新が集中しました。 Bedrock まわりのアップデートが引き続き活発に行われる中、Webアプリ構築でよく使う基本サービスにも多くの改良がありました。特に、Amazon Aurora PostgreSQL がついに無料利用枠で使えるようになったのは大きな変化で、今後は Aurora を活用したアプリ開発がさらに進みそうだと感じています。 それでは、また来週お会いしましょう! 著者について 戸塚 智哉(Tomoya Tozuka) / @tottu22 飲食やフィットネス、ホテル業界全般のお客様をご支援しているソリューション アーキテクトで、AI/ML、IoT を得意としています。最近では AWS を活用したサステナビリティについてお客様に訴求することが多いです。 趣味は、パデルというスペイン発祥のスポーツで、休日は仲間とよく大会に出ています。
はじめに はじめまして。 KINTO テクノロジーズで KINTO Unlimited Android アプリを開発している JR.Liang です。 本記事では、KINTO Unlimited アプリにて提供する「これなにガイド」スキャン機能の AR エフェクトについて、Android における技術的な検証を紹介します。 特に MediaPipe のソリューションを用いて幅広い Android デバイスで AR エフェクトを実現した実装にフォーカスします。 これなにガイドとは 「これなにガイド」は AR(拡張現実)を活用して、車内スイッチの用途や使い方をテキストと動画で案内する機能です。紹介動画をご覧ください。 https://youtube.com/watch?v=E8zfNzuHr7g&embeds_referring_euri=https%3A%2F%2Fcorp.kinto-jp.com%2F&source_ve_path=MjM4NTE 上記の紹介動画は iOS アプリでの動作を示しています。スイッチ上に表示された黄色の丸 🟡 が、AR 技術で実現した仮想コンテンツです。 機能全体の仕組みは以下の流れです。本記事では 3 番目(描画)に関する内容を扱います。 1. アプリのカメラを起動、カメラ画像を取得 2. 機械学習における物体認識を用いて、車内のスイッチを検出 3. 検出した座標を元に、ボタンとテキストをフレーム上に描画 4. ボタンをタップして、当該スイッチのテキストと動画を表示 Android AR 技術検証の経緯 当初の Android 版「これなにガイド」のスキャン機能では、Canvas を利用して毎フレーム検出される座標に描画する実装でした。そのため検出の時間差により、スマホ(カメラ)を動かすと描画のズレが生じていました。 2D Canvas 幸い、MediaPipe のソリューションである Instant Motion Tracking モジュールで 素早くかつ安定した AR エフェクトを実現できることがわかり、Android への導入を検証しました。 3D OpenGL MediaPipe Instant Motion Tracking MediaPipe は Google が開発したオープンソースの ML フレームワークで、顔検出・手のトラッキング・姿勢推定などリアルタイム映像処理のソリューションを提供します。 その中の Instant Motion Tracking は、現実世界のシーン上に 3D 仮想コンテンツをリアルタイムで正確に配置できる AR トラッキング機能です。初期化や厳密なキャリブレーションが不要で、静止面や動いている面の上にコンテンツを置くことが可能です。 @ card Android + MediaPipe AR アーキテクチャ graph TB A(Android CameraX) --> |Camera Frame| B(Instant Motion Tracking) B --> |Camera Image| C(TensorFlow Object Detection) C --> |Detections Information| B(Instant Motion Tracking) B --> |Output Stream| D(Android Surface Rendering) CameraX で取得したフレームを Instant Motion Tracking に渡し、TensorFlow Lite で物体検出した情報を元に AR コンテンツを描画・追従させるパイプラインです。 MediaPipe ライブラリの作成 MediaPipe では Bazel を使用してパッケージをビルドします。Android に適合する AAR として書き出してアプリに組み込みます。 https://chuoling.github.io/mediapipe/getting_started/android_archive_library.html AAR をビルドする BUILD ファイルを作成し、 instant_motion_tracking を基盤とした定義を記述します。 load("//mediapipe/java/com/google/mediapipe:mediapipe_aar.bzl", "mediapipe_aar") mediapipe_aar( name = "mediapipe_ar", calculators = ["//mediapipe/graphs/instant_motion_tracking:instant_motion_tracking_deps"] ) MediaPipe は C++ が中核のため、C++ ランタイムである libc++_shared.so を AAR に同梱する必要があります。 https://github.com/google-ai-edge/mediapipe/blob/v0.10.32/third_party/BUILD#L399-L403 また Instant Motion Tracking では画像処理ライブラリ OpenCV を利用し、AR トラッキングを行います。 https://github.com/google-ai-edge/mediapipe/blob/v0.10.32/WORKSPACE#L649-L655 上記サードパーティのライブラリを含めて、以下のコマンドで AAR をビルドします。 bazel build -c opt --strip=ALWAYS \ --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \ --fat_apk_cpu=arm64-v8a \ --linkopt=-Wl,-z,max-page-size=16384 \ //path/to/the/aar/build/mediapipe_ar:mediapipe_ar.aar 市場に流通している Android デバイスは主に arm64-v8a アーキテクチャのため、AAR のサイズを抑える目的で fat_apk_cpu=arm64-v8a にします。 C++ ライブラリの 16KB page-size に対応するため、 max-page-size=16384 を追加します。 また AAR を利用するにはグラフ構造を定義するファイル( binarypb )が必要です。 bazel build -c opt mediapipe/graphs/instant_motion_tracking:instant_motion_tracking.binarypb Instant Motion Tracking の導入 AAR をアプリに組み込んで、Android 側の実装を解説していきます。 下記は AAR に組み込んだ instant_motion_tracking の全体構造です。 instant_motion_tracking.pbtxt の構成 グラフ定義ファイル instant_motion_tracking.pbtxt は、Calculator(処理ノード)・入出力ストリーム・サイドパケットの 3 要素で構成されます。 Calculator 各 Calculator がパイプライン上でどの処理を担うかを示します。 Calculator 役割 ImageTransformationCalculator カメラフレームを 320×320(FIT)にリサイズ。物体検出モデルの入力サイズに合わせる GpuBufferToImageFrameCalculator GPU テクスチャを CPU の ImageFrame に変換。TensorFlow Lite 推論に使用 StickerManagerCalculator Sticker Proto をパースし、初期アンカーの座標・回転・スケール・レンダリング種別に分解 RegionTrackingSubgraph ボックストラッキングでアンカー位置を追従。内部に TrackedAnchorManagerCalculator (アンカー管理)と BoxTrackingSubgraphGpu (GPU トラッキング)を持つ MatricesManagerCalculator トラッキング結果・回転・スケール・FOV・アスペクト比から OpenGL 用 4×4 モデル行列を生成 GlAnimationOverlayCalculator モデル行列とテクスチャを用いて、元のカメラフレーム上に AR コンテンツを OpenGL で描画し output_video として出力 input_stream / output_stream input_stream はフレームごとに Android 側から送信するデータ、 output_stream はグラフの処理結果です。 ストリーム名 C++ 型 方向 用途 input_video GpuBuffer Input カメラフレーム sticker_proto_string String(Serialized Proto) Input ステッカーの座標・スケール等(Sticker Proto) sticker_sentinels vector Input 座標をリセットするステッカー ID の配列 gif_textures vector Input AR コンテンツの Bitmap テクスチャ配列 gif_aspect_ratios vector Input 各テクスチャのアスペクト比 output_video GpuBuffer Output AR 描画済みフレーム input_side_packet input_side_packet は初期化時に一度だけ渡す定数で、グラフ実行中は変化しません。 パケット名 用途 vertical_fov_radians カメラの垂直 FOV(ラジアン) aspect_ratio カメラのアスペクト比 width / height カメラ解像度 gif_texture デフォルトテクスチャ(1x1 プレースホルダ) gif_asset_name AR テクスチャ描画用のポリゴンメッシュ( .obj )ファイル名 Android への導入に当たって、公式サンプルのコードを参考にします。 https://github.com/google-ai-edge/mediapipe/tree/master/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking 1. 初期化 MediaPipe を使用する前に、ネイティブライブラリの読み込みとアセットマネージャーの初期化が必要です。 companion object { init { System.loadLibrary("mediapipe_jni") System.loadLibrary("opencv_java4") } } // onCreate 相当の処理 AndroidAssetUtil.initializeNativeAssetManager(context) mediapipe_jni : MediaPipe のコア処理を行う JNI ライブラリ opencv_java4 : AR トラッキングに使用する OpenCV ライブラリ initializeNativeAssetManager : ネイティブコードからアセット(binarypb 等)にアクセスするために必要 2. カメラを起動する 公式サンプルを参考に、以下の順序でパイプラインを構築します。 データフロー: CameraX → ExternalTextureConverter → FrameProcessor → SurfaceView 2.1 EGL 環境と FrameProcessor の初期化 val eglManager = EglManager(null) val frameProcessor = FrameProcessor( context, eglManager.nativeContext, "instant_motion_tracking.binarypb", "input_video", "output_video" ).apply { videoSurfaceOutput.setFlipY(true) setInputSidePackets( mapOf( "gif_asset_name" to packetCreator.createString("gif.obj.uuu"), "vertical_fov_radians" to packetCreator.createFloat32(fovRadians), "aspect_ratio" to packetCreator.createFloat32(resolution.width.toFloat() / resolution.height.toFloat()), "width" to packetCreator.createInt32(resolution.width), "height" to packetCreator.createInt32(resolution.height), "gif_texture" to packetCreator.createRgbaImageFrame(createBitmap(1, 1)) ) ) } EglManager : OpenGL ES の EGL コンテキストを作成・管理。MediaPipe のグラフ内 GPU Calculator( GlAnimationOverlayCalculator 等)が OpenGL で描画するために必要 FrameProcessor : EGL コンテキストを受け取り、グラフの読み込み・入出力ストリームの管理・フレームごとのグラフ実行を行う instant_motion_tracking.binarypb : .pbtxt を Bazel でコンパイルしたグラフ定義バイナリ input_video : MediaPipe グラフへカメラフレームを入力 output_video : グラフで処理(AR 描画など)された映像を出力 videoSurfaceOutput.setFlipY(true) : OpenGL とカメラの Y 軸方向が逆のため、出力映像を上下反転して正しい向きにする setInputSidePackets : グラフの input_side_packet に対応する定数をまとめて設定。カメラの FOV・アスペクト比・解像度など、グラフ実行中に変化しない値を初期化時に一度だけ渡す gif_asset_name は AR テクスチャを描画するための ポリゴンメッシュ(頂点データ) 、ここでは公式サンプルの gif.obj.uuu を利用 2.2 カメラ映像の変換パイプライン構築 val externalTextureConverter = ExternalTextureConverter(eglManager.context, 2).apply { setFlipY(true) setConsumer(frameProcessor) setDestinationSize(resolution.width, resolution.height) } val cameraHelper = object : CameraXPreviewHelper() { override fun getCameraCharacteristics(context: Context?, lensFacing: Int?) = cameraCharacteristics }.apply { setOnCameraStartedListener(onCameraStartedListener) startCamera( context, lifecycleOwner, CameraHelper.CameraFacing.BACK, externalTextureConverter.surfaceTexture, Size(resolution.height, resolution.width) ) } ExternalTextureConverter : カメラの GL_EXTERNAL_OES テクスチャを MediaPipe が処理できる標準テクスチャに変換 setFlipY(true) : カメラ映像の上下反転を補正 setDestinationSize(resolution.width, resolution.height) : パイプラインの処理サイズはポートレート座標(例: 960×1280 )で指定 CameraXPreviewHelper : CameraX でバックカメラを起動し、Converter の SurfaceTexture に出力 startCamera(targetSize = Size(resolution.height, resolution.width)) : CameraX はセンサー座標(ランドスケープ)を期待するため、width と height を入れ替えて渡す 公式サンプルでは CameraXPreviewHelper をそのまま使用し、内部で CameraManager からカメラ特性を取得します。 https://github.com/google-ai-edge/mediapipe/blob/v0.10.32/mediapipe/java/com/google/mediapipe/components/CameraXPreviewHelper.java#L558-L560 本実装では getCameraCharacteristics をオーバーライドし、事前に取得済みの CameraCharacteristics を直接渡します。これにより FOV やアスペクト比の算出に使うカメラ情報を、アプリ側で一元管理できます。 2.3 出力先SurfaceViewの設定 SurfaceView(context).apply { holder.addCallback(object : SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { frameProcessor.videoSurfaceOutput.setSurface(holder.surface) } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { val displaySize = cameraHelper.computeDisplaySizeFromViewSize(Size(width, height)) val (displayWidth, displayHeight) = if (cameraHelper.isCameraRotated) { displaySize.height to displaySize.width } else { displaySize.width to displaySize.height } externalTextureConverter.setDestinationSize(displayWidth, displayHeight) } override fun surfaceDestroyed(holder: SurfaceHolder) { frameProcessor.videoSurfaceOutput.setSurface(null) } }) } SurfaceHolder.Callback : SurfaceView のライフサイクルに応じて FrameProcessor の出力先を管理 surfaceCreated : FrameProcessor の出力先として Surface を設定 surfaceChanged : 画面回転・サイズ変更時に出力解像度を調整 surfaceDestroyed : リソース解放 3. 検出座標をグラフに渡す 物体検出(TensorFlow Lite 等)で得られた座標を MediaPipe グラフに渡し、AR コンテンツを配置します。 3.1 グラフから変換済み画像を取得 MediaPipe グラフ内で ImageTransformationCalculator と GpuBufferToImageFrameCalculator によって変換された画像を addPacketCallback で受け取り、物体検出に使用します。 frameProcessor.addPacketCallback("transformed_input_video_cpu") { packet -> packet ?: return@addPacketCallback // 変換済み画像を物体検出(TensorFlow Lite)に渡す val bitmap = PacketGetter.getBitmapFromRgba(packet) objectDetector.detect(bitmap) { detections -> // 検出結果を処理 } } transformed_input_video_cpu : 変換後の画像を出力するストリーム名 3.2 座標の正規化 物体検出結果のピクセル座標を、MediaPipe が期待する正規化座標に変換します。 // ピクセル座標 → 正規化座標 (0.0〜1.0) val normalizedX = pixelX / imageWidth.toFloat() val normalizedY = pixelY / imageHeight.toFloat() 3.3 Sticker Proto の構造 Instant Motion Tracking では、AR オブジェクトの位置情報を Protocol Buffers 形式で定義します。 message Sticker { int32 id = 1; // ユニークID float x = 2; // 正規化X座標 (0.0〜1.0) float y = 3; // 正規化Y座標 (0.0〜1.0) float rotation = 4; // 回転角度 float scale = 5; // スケール int32 render_id = 6; // レンダリングID } message StickerRoll { repeated Sticker sticker = 1; } 3.4 フレームごとにパケットを送信 setOnWillAddFrameListener を使用して、各フレーム処理前に検出座標をグラフへ送信します。 frameProcessor.setOnWillAddFrameListener { timestamp -> with(frameProcessor.graph) { // 検出された物体の座標情報をパケットとして送信 val stickerRoll = StickerRoll.newBuilder() .addAllSticker(detectedObjects.map { detection -> Sticker.newBuilder() .setId(detection.id) .setX(detection.normalizedX) // 0.0〜1.0 .setY(detection.normalizedY) // 0.0〜1.0 .setScale(detection.scale) .build() }) .build() val stickersPacket = packetCreator.createSerializedProto(stickerRoll) addPacketToInputStream("sticker_proto_string", stickersPacket, timestamp) } } FrameProcessor.setOnWillAddFrameListener : 各フレームがグラフに送られる直前に呼ばれるコールバック FrameProcessor.graph.addPacketToInputStream : 入力ストリームにパケットを追加 sticker_proto_string : グラフ定義で指定された入力ストリーム名 4. テクスチャ(Bitmap)の描画と送信 位置情報と同時に、AR コンテンツとして描画する Bitmap テクスチャもグラフに渡します。 4.1 Bitmap テクスチャの生成 検出された各スイッチに対して、丸アイコンとラベルテキストを含む Bitmap を生成します。 val bitmap = createBitmap(width.toInt(), height.toInt()).apply { with(Canvas(this)) { concat(Matrix().apply { preScale(-1.0f, 1.0f, width / 2f, height / 2f) // X軸を反転して描画 }) drawCircle(circleX, circleY, CIRCLE_RADIUS, circlePaint) drawRect(rectLeft, rectTop, rectRight, rectBottom, backgroundPaint) } } Matrix().preScale(-1.0f, 1.0f) で Bitmap を左右反転しています。以下の IMU 行列に合わせるためです。 float imu_matrix[9] = { -1.0f, 0.0f, 0.0f, // X軸 → 反転(-X) 0.0f, 0.0f, 1.0f, // Y軸 → Z軸へ 0.0f, 1.0f, 0.0f // Z軸 → Y軸へ }; この行列は OpenGL モデル行列(4x4)の回転成分として使われ、Y/Z 軸の入れ替えと X 軸反転でテクスチャをカメラ平面に平行に固定します。 本来はデバイスの IMU センサーから回転行列を受け取り、端末の傾きに追従させます。 https://github.com/google-ai-edge/mediapipe/blob/0.10.32/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/MainActivity.java#L218-L220 本実装では固定値にすることで 常にカメラ正面を向く (ビルボード効果)ようにし、 (0,0) の -1.0 による X 軸反転を Bitmap 側の preScale(-1.0f, 1.0f) で打ち消します。 4.2 テクスチャの送信 // テクスチャ画像(Bitmap配列) val texturesPacket = packetCreator.createRgbaImageFrameVector( renderStickers.map { it.bitmap }.toTypedArray() ) addPacketToInputStream("gif_textures", texturesPacket, timestamp) // アスペクト比(テクスチャの縦横比) val aspectRatiosPacket = packetCreator.createFloat32Vector( renderStickers.map { it.aspectRatio }.toFloatArray() ) addPacketToInputStream("gif_aspect_ratios", aspectRatiosPacket, timestamp) PacketCreator.createRgbaImageFrameVector : 複数の Bitmap を RGBA 形式のパケットに変換 gif_textures : テクスチャ画像の入力ストリーム gif_aspect_ratios : 各テクスチャのアスペクト比(正しいスケーリングに必要) 公式サンプルでは createRgbaImageFrame を使用して 単一のテクスチャ をグラフに渡します。 https://github.com/google-ai-edge/mediapipe/blob/0.10.32/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/MainActivity.java#L608-L610 本実装では、複数の検出オブジェクトに対応するため createRgbaImageFrameVector で 複数テクスチャを同時に送信 し、 gif_aspect_ratios も createFloat32Vector で 各テクスチャに対応するアスペクト比の配列 を渡すよう拡張します。これにより、検出された各スイッチに異なるラベル(テキスト付きBitmap)を正しい縦横比で表示できます。 ここまでで AR コンテンツをカメラ上に表示できました。 5. 座標の更新 トラッキング中のステッカー座標を更新するには、新しい座標を持つ sticker_proto_string と、リセット対象の ID を含む sticker_sentinels を同一 timestamp で送信します。 TrackedAnchorManagerCalculator が該当 ID のトラッキングボックスを破棄し、新しい座標でトラッキングを再開します。 // 更新した座標で Sticker Proto を再構築 val stickersPacket = packetCreator.createSerializedProto(stickerRoll) addPacketToInputStream("sticker_proto_string", stickersPacket, timestamp) // リセット対象のステッカー ID を送信 val stickerSentinels = packetCreator.createInt32Vector(updateIds) addPacketToInputStream("sticker_sentinels", stickerSentinels, timestamp) 公式サンプルでは sticker_sentinel で 単一のステッカー ID を送信します。 https://github.com/google-ai-edge/mediapipe/blob/0.10.32/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/MainActivity.java#L342-L344 本実装では sticker_sentinels として createInt32Vector で 複数のステッカー ID を配列 で渡すよう拡張し、物体検出で座標が更新された複数のステッカーを同時にリセットできるようにします。 最後に 以上が MediaPipe Instant Motion Tracking を用いた技術的な実装解説でした。決して容易に導入できる手法ではありませんが、本機能の要件に対して Android に最も適した解決策だと考えています。 以前に ARCore の検証も行いましたが、ARCore は SLAM 技術による事前の 3D マッピングに時間を要し、 素早くかつ安定した AR エフェクトの実現には適さなかったため、検証を断念しました。 両フレームワークの違いを以下にまとめます。AR 技術の検討で参考になれば幸いです。 項目 Instant Motion Tracking ARCore 仕組み 2D ボックストラッキング + OpenGL 描画 環境マッピング + 平面検出(SLAM) デバイス要件 OpenGL ES 対応であれば動作 ARCore 対応デバイスのみ(Google 認定必須) 安定性 検出座標に依存するため補正が必要 空間認識が高精度で安定 導入コスト Bazel ビルド・C++ Calculator のカスタマイズが必要 SDK 導入のみで比較的容易 オープンソース あり(Apache 2.0) なし(プロプライエタリ) カスタマイズ性 Calculator の追加・変更で柔軟に拡張可能 SDK の API 範囲内に限定 パフォーマンス 軽量(2D トラッキングベースのため CPU/GPU 負荷が低い) 高負荷(環境の 3D 空間マッピングを常時実行) 学習コスト 高い(Bazel・C++・OpenGL・Protocol Buffers の知識が必要) 低い(Android SDK の知見で導入可能)






















