人間の視覚的注意をシミュレートするリカレントニューラルネットワークを実装するにはどうすればよいでしょうか?

人間の視覚的注意をシミュレートするリカレントニューラルネットワークを実装するにはどうすればよいでしょうか?

原理

この記事で使用されているコードは、https://github.com/SquarePants1991/OpenGLESLearn.git の ARKit ブランチにあります。

iOS11では新しいフレームワークARKitが導入され、ARKitとSceneKitを通じてARアプリを簡単に作成できるようになりました。 Apple は基本的な AR アプリケーション フレームワークも提供しており、そこから直接 AR アプリの開発を開始できます。

ただし、このシリーズの記事では、OpenGL ES を使用して ARKit のレンダリング サポートを提供します。次に、まず ARKit の理論的な知識について学習しましょう。

ARの基本概念

AR の最も基本的な概念は、仮想コンピュータグラフィックスと実際の環境を組み合わせる技術です。このテクノロジーを実装する方法は多数あります。

  • 2D または 3D グラフィックを使用して顔を装飾することは、主に顔認識および追跡テクノロジーを使用して、一部のカメラ アプリやビデオ アプリで一般的です。

  • AR ベースのストーリーブックや現実世界での陰陽師の召喚など、マーカーベースの 3D モデル配置。マーカーは、単純な黒いフレームでも、複雑な画像の特徴点トレーニング データでもかまいません。ご興味があれば、マーカーベースの AR に主に使用されるオープンソースの AR フレームワークである ARToolKit をご覧ください。最近、ARToolkit6 ベータ版がリリースされました。何か新しい機能があるのでしょうか。

  • 実際の環境の特徴点を追跡し、実際の環境における実際のカメラの位置を計算します。いわゆる特徴点とは、画像内でグレースケールの変化がより急激な場所です。したがって、より正確で安定した計算を行うには、実際の環境でより豊かな色の変化を実現する必要があります。 ARKit はカメラの配置にこの原理を使用します。

ワールドトラッキング

現実世界の特徴点を追跡し、実際のカメラの位置を計算し、それを 3D 世界の仮想カメラに適用することが、AR 実装の最も重要な部分です。計算結果の精度はレンダリング結果に直接影響します。 ARKit は、カメラ位置の計算を含む AR 処理フロー全体を ARSession を使用して管理します。

#pragma make - AR コントロール
- (void)セットアップAR {
    (@利用可能(iOS 11.0、*)) {
        self.arSession = [ARSession新規];
        self.arSession.delegate = 自分;
    }
}

- (void)runAR {
    (@利用可能(iOS 11.0、*)) {
        ARWorldTrackingSessionConfiguration *config = [ARWorldTrackingSessionConfiguration new];
        config.planeDetection = ARPlaneDetectionHorizo​​ntal;
        [self.arSession 実行構成:config];
    }
}

- (void)一時停止AR {
    (@利用可能(iOS 11.0、*)) {
        [self.arSession 一時停止];
    }
}

ARSession の使い方は非常に簡単です。デリゲートを初期化して設定します。ARSession を開始するには、構成 ARWorldTrackingSessionConfiguration を渡す必要があります。ARWorldTrackingSessionConfiguration は、AR システムが現実世界の特徴点を追跡し、カメラの位置を計算することを意味します。 Apple は将来、トラッキング マーカーを識別するために ARMarkerTrackingSessionConfiguration などの構成をリリースする可能性もあります。 ARSession をオンにすると、カメラが起動し、センサーを通じて携帯電話の位置が感知されます。 WWDCから写真を拝借。

ARSession は、カメラでキャプチャされたビデオ ストリームと位置情報を統合して、一連の連続した ARFrame を生成します。

- (void)セッション:(ARSession *)セッションdidUpdateFrame:(ARFrame *)フレーム{
...
}

各 ARFrame には、カメラで撮影された画像やカメラの位置に関する情報などが含まれます。この方法では、カメラで撮影した画像を描画する必要があります。カメラの位置などの情報に基づいて 3D オブジェクトを描画します。

平面検出

ARKit には、現実世界の平面を検出し、平面の位置、サイズ、方向、その他の情報を記述する ARPlaneAnchor オブジェクトを提供するという、もう 1 つの優れた機能があります。

- (void)runAR {
    (@利用可能(iOS 11.0、*)) {
        ARWorldTrackingSessionConfiguration *config = [ARWorldTrackingSessionConfiguration new];
        config.planeDetection = ARPlaneDetectionHorizo​​ntal;
        [self.arSession 実行構成:config];
    }
}

上記の config.planeDetection = ARPlaneDetectionHorizo​​ntal; は、検出された平面のタイプを水平に設定します。ただし、これが現在利用できる唯一のオプションです。 ARKit が平面を検出すると、デリゲート メソッド (void)session:(ARSession *)session didAddAnchors:(NSArray *)anchors を通じてデータが提供されます。 ARAnchor が ARPlaneAnchor であるかどうかを判断し、平面が検出されたかどうかを判断できます。 ARAnchor は、実際の環境における 3D オブジェクトの位置を表すために使用されます。 3D オブジェクトと ARAnchor の 3D 変換を同期させるだけで、AR 効果を実現できます。

ヒットテスト

ヒット テストを使用すると、検出された平面にオブジェクトを簡単に配置できます。画面をタップすると、Hit Test を使用してタップした場所にある平面を検出し、オブジェクトが配置される場所を設定するための ARAnchor を提供します。

[フレーム hitTest:CGPointMake(0.5, 0.5) タイプ:ARHitTestResultTypeExistingPlane];

ARFrame の hitTest メソッドを使用すると、渡される最初のポイントの範囲は (0,0) から (1,1) までとなり、2 番目のパラメータは検出できるオブジェクトを表します。検出できる物体は以下の通りです。

  • ARHitTestResultTypeFeaturePoint、最も近い特徴点に基づいて検出された連続サーフェス。

  • ARHitTestResultTypeEstimatedHorizo​​ntalPlane では、重力に対して垂直な平面が不正確に計算されます。

  • ARHitTestResultTypeExistingPlane では、平面が検出され、検出時に平面自体のサイズは無視され、無限平面とみなされます。

  • ARHitTestResultTypeExistingPlaneUsingExtent では、検出された平面は検出時に平面自体のサイズを考慮します。

検出が成功すると、NSArray * が返されます。ARHitTestResult には、検出タイプ、交差点の距離、平面の ARAnchor が含まれます。 ARAnchor は、ARHitTestResultTypeExistingPlane と ARHitTestResultTypeExistingPlaneUsingExtent が検出された場合にのみ使用可能であることに注意してください。これら 4 つのテスト タイプは、ARHitTestResultTypeEstimatedHorizo​​ntalPlane | ARHitTestResultTypeExistingPlane のように、| の形式で同時に存在できます。

光量調整

ARKit は、主に 3D モデルの照明強度を環境​​の照明強度と一致させるために、光の強度を検出する機能も提供します。 ARFrame には lightEstimate 変数があり、光の強度が正常に検出された場合に値が設定されます。値の型は ARLightEstimate で、1 つの変数 (ambientIntensity) のみが含まれます。 3D 照明モデルでは、周囲光に対応し、その値の範囲は 0 ~ 2000 です。 OpenGL でレンダリングする場合、この値を使用して照明モデルの周囲光の強度を調整できます。

ARKit の理論的な知識はこれでほぼ終わりです。次の記事では、OpenGL ES を使用して ARFrame のコンテンツをレンダリングする方法を紹介します。

実装

この記事で使用されているコードは、https://github.com/SquarePants1991/OpenGLESLearn.git の ARKit ブランチにあります。

この記事で使用している OpenGL の基本コードは、ジオメトリやテクスチャのレンダリングなどの基本機能を備えた OpenGL ES シリーズのものです。実装の詳細については繰り返しません。

ARKit を統合するためのキーコードは ARGLBaseViewController にあります。コードを見てみましょう。

ARFrameの処理

- (void)セッション:(ARSession *)セッションdidUpdateFrame:(ARFrame *)フレーム{
    // YUV情報をyTextureとuvTextureに同期する
    CVPixelBufferRef ピクセルバッファ = frame.capturedImage;
    GLsizei 画像の幅 = (GLsizei)CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
    GLsizei イメージの高さ = (GLsizei)CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
    void * ベースアドレス = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);

    glBindTexture(GL_TEXTURE_2D、self.yTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 画像幅、画像高さ、0, GL_LUMINANCE, GL_UNSIGNED_BYTE, ベースアドレス);
    glBindTexture(GL_TEXTURE_2D, 0);

    画像の幅 = (GLsizei)CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
    画像の高さ = (GLsizei)CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
    void *laAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
    glBindTexture(GL_TEXTURE_2D、self.uvTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 画像の幅、画像の高さ、0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, laAddress);
    glBindTexture(GL_TEXTURE_2D, 0);

    self.videoPlane.yuv_yTexture = self.yTexture;
    self.videoPlane.yuv_uvTexture を self.uvTexture に追加します。
    [自己設定ビューポート: CGSizeMake(imageHeight, imageWidth)];

    // カメラを同期する matrix_float4x4 cameraMatrix = matrix_invert([frame.camera transform]);
    GLKMatrix4 の新しいカメラマトリックス = GLKMatrix4Identity;
    (int col = 0; col < 4; ++col) の場合 {
        (int row = 0; row < 4; ++row) の場合 {
            newCameraMatrix.m[列 * 4 + 行] = cameraMatrix.columns[列][行];
        }
    }

    self.cameraMatrix = 新しいカメラマトリックス;
    GLKVector3 を forward = GLKVector3Make(-self.cameraMatrix.m13, -self.cameraMatrix.m23, -self.cameraMatrix.m33);
    GLKMatrix4 回転行列 = GLKMatrix4MakeRotation(M_PI / 2、forward.x、forward.y、forward.z);
    self.cameraMatrix = GLKMatrix4Multiply(回転マトリックス、新しいカメラマトリックス);
}

上記のコードは、ARKit でキャプチャした ARFrame を処理する方法を示しています。ARFrame の capturedImage には、カメラでキャプチャした画像情報が格納されており、その型は CVPixelBufferRef です。デフォルトでは、画像情報の形式は YUV であり、2 つのプレーンに保存され、2 つの画像としても理解されます。 1 つの形式は、明るさの情報を格納する Y (輝度) で、もう 1 つは彩度と濃度を格納する UV (色度、彩度) です。これら 2 つの画像をそれぞれ異なるテクスチャにバインドし、Shader のアルゴリズムを使用して YUV を RGB に変換する必要があります。以下はテクスチャを処理し、色変換の式を使用するフラグメント シェーダーです。

高精度の高浮動小数点数。

変化する vec3 fragNormal;
変化するvec2 fragUV;

均一な float 経過時間;
均一mat4通常行列;
均一サンプラー2D yMap;
均一サンプラー2D uvMap;

void main(void) {
    vec4 Y_planeColor = texture2D(yMap, fragUV);
    vec4 CbCr_planeColor = texture2D(uvMap, fragUV);

    Cb、Cr、Yを浮動小数点数化します。
    R、G、Bを浮動小数点数化します。
    Y = Y_planeColor.r * 255.0;
    Cb = CbCr_planeColor.r * 255.0 - 128.0;
    Cr = CbCr_planeColor.a * 255.0 - 128.0;

    R = 1.402 * Cr + Y;
    G = -0.344 * Cb - 0.714 * Cr + Y;
    B = 1.772 * Cb + Y;


    vec4ビデオカラー = vec4(R / 255.0, G / 255.0, B / 255.0, 1.0);
    gl_FragColor = ビデオカラー;
}

テクスチャを処理してバインドした後、異なる画面サイズでテクスチャが不均一に引き伸ばされないようにするために、ビューポートが再計算されます [self setupViewport: CGSizeMake(imageHeight, imageWidth)];。次に、ARKit によって計算されたカメラ変換を self.cameraMatrix に割り当てます。なお、ARKit でキャプチャした画像は正しく表示するには 90 度回転させる必要があるため、Viewport を設定する際に意図的に幅と高さを反転し、最後にカメラを回転させます。

ビデオプレーン

VideoPlane はビデオを表示するために書き込まれたジオメトリであり、Y と UV の 2 つのテクスチャを受け取ることができます。

@interface ビデオプレーン : GLObject
@property (割り当て、非アトミック) GLuint yuv_yTexture;
@property (割り当て、非アトミック) GLuint yuv_uvTexture;
- (インスタンスタイプ)initWithGLContext:(GLContext *)コンテキスト;
- (void)update:(NSTimeInterval)timeSinceLastUpdate;
- (void)draw:(GLContext *)glContext;
@終わり

...

- (void)draw:(GLContext *)glContext {
    [glContext setUniformMatrix4fv:@"modelMatrix" 値:self.modelMatrix];
    ブール値は反転できます。
    GLKMatrix4 の normalMatrix を GLKMatrix4InvertAndTranspose(self.modelMatrix, &canInvert);
    [glContext setUniformMatrix4fv:@"normalMatrix" 値:canInvert ? normalMatrix : GLKMatrix4Identity];
    [glContext bindTextureName:self.yuv_yTexture to:GL_TEXTURE0 universeName:@"yMap"];
    [glContext bindTextureName:self.yuv_uvTexture to:GL_TEXTURE1 universeName:@"uvMap"];
    [glContext drawTrianglesWithVAO:vao 頂点数:6];
}

他の機能は非常にシンプルで、正方形を描画し、最後にシェーダーと連携してビデオを表示し、データを YUV 形式でレンダリングします。

透視投影マトリックス

ARFrame では、レンダリングに必要なテクスチャとカメラ行列を取得できます。これらに加えて、実際のカメラに合わせた透視投影行列も必要です。レンダリングされた 3D オブジェクトの遠近感が自然に見えるようになります。

- (void)セッション:(ARSession *)セッション cameraDidChangeTrackingState:(ARCamera *)カメラ {
    matrix_float4x4 projectionMatrix = [カメラ projectionMatrixWithViewportSize:self.viewport.size orientation:UIInterfaceOrientationPortrait zNear:0.1 zFar:1000];
    GLKMatrix4 の新しいワールド投影マトリックス = GLKMatrix4Identity;
    (int col = 0; col < 4; ++col) の場合 {
        (int row = 0; row < 4; ++row) の場合 {
           新しいWorldProjectionMatrix.m[列 * 4 + 行] = projectionMatrix.columns[列][行];
        }
    }
    self.worldProjectionMatrix = 新しいWorldProjectionMatrix;
}

上記のコードは、ARKit を通じて 3D 透視投影行列を取得する方法を示しています。透視投影行列とカメラ行列を使用すると、OpenGL を使用してオブジェクトを簡単にレンダリングできます。

- (void)glkView:(GLKView *)ビューdrawInRect:(CGRect)rect {
    [スーパー glkView:ビュー drawInRect:rect];

    [self.objects enumerateObjectsUsingBlock:^(GLObject *obj, NSUInteger idx, BOOL *stop) {
        [obj.context アクティブ];
        [obj.context setUniform1f:@"elapsedTime" 値:(GLfloat)self.elapsedTime];
        [obj.context setUniformMatrix4fv:@"projectionMatrix" 値:self.worldProjectionMatrix];
        [obj.context setUniformMatrix4fv:@"cameraMatrix" 値:self.cameraMatrix];

        [obj.context setUniform3fv:@"lightDirection" 値:self.lightDirection];
        [obj 描画:obj.context];
    }];
}

この記事では、OpenGL ES の技術的な詳細についてはあまり説明せずに、主に OpenGL ES レンダリング ARKit の基本的な考え方を紹介します。興味がある場合は、Github でコードを直接クローンして詳細を確認できます。

<<:  長いテキストの復号化畳み込みニューラルネットワークアーキテクチャ

>>:  人工知能オンライン機能システムのデータアクセス技術

ブログ    
ブログ    

推薦する

...

アンドリュー・ン氏の新演説:AIは業界の状況を変えており、企業の障壁はアルゴリズムではなくデータである

[[204846]] 1. 人工知能の応用と価値Andrew Ng 氏は、AI は新しい電気であると...

...

AlphaCode がリリースされました! 「AlphaGo」のプログラミング版が静かに競争し、プログラマーの半数を破る

本日、DeepMind の「Alpha」ファミリーに新しいメンバーが加わりました。プログラミング競技...

Java プログラミング スキル - データ構造とアルゴリズム「バイナリ ソート ツリー」

[[390181]]基本的な紹介バイナリ ソート (検索) ツリー: バイナリ ソート ツリー内の...

AIに「擬人化技術」を使う?人工知能による認識への道は長く困難である

人工知能アルゴリズムやディープラーニングなどのさまざまな技術の徹底的な発展により、人工知能(AI)は...

学術界の巨人たちのブラックテクノロジー:人工知能のダークマターについて聞いたことがありますか?

北京大学の公式サイトの最新情報によると、元UCLA(カリフォルニア大学ロサンゼルス校)教授の朱松春...

AIミドルプラットフォーム - インテリジェントチャットボットプラットフォームのアーキテクチャとアプリケーション

講演者紹介:王東:北京大学大学院 CreditEase テクノロジーセンター AI ミドルプラットフ...

オーストラリアの裁判所は、特許出願においてAIを発明者とみなすことができると判決を下した。

[[415316]]海外メディアの報道によると、オーストラリアの裁判所は、特許出願において人工知能...

スマートシティ交通ソリューションへのテクノロジーの影響

インテリジェントな交通管理システムは、スマートシティの開発に欠かせない要素です。具体的には、スマート...

ホスピタリティ業界における職場の変革 - 人間と機械の関係

ホスピタリティ業界は、過去数十年にわたって多くの世界的な混乱を経験してきたサービスベースの業界です。...

...

...

AIによる顔の変形の背後にある技術的な戦い

[[275567]]週末に集中的に流行した後、顔を変えるソフトウェアZAOの人気はようやく落ち着きを...