web-dev-qa-db-ja.com

OpenCV + Android + Unity

UnityプロジェクトでOpenCVを使用する方法を探しています。私のターゲットプラットフォームはAndroidデバイスです。

Unityアセットストアにいくつかのアセットが存在することを知っていますが、私はしないでください非常に高価であるため、それらを使用します。

this チュートリアルを使用してdllでOpenCVをプリコンパイルすることにより、UnityでopencvをC++ネイティブプラグインとして使用できますが、dllはWindowsデスクトップを意味するため、Android用のプロジェクトをビルドするのにあまり役立ちません。

また、opencv jarアーカイブも見つかりました。Unityに簡単にインポートできることはわかっていますが、次のステップの方法がわかりません。つまり、Unity C#スクリプトからOpenCVにアクセスする方法です。

そのため、UnityエディターでOpenCVを使用してダミーのhello worldプロジェクトを構成してAndroidにビルドする方法を知っている人や、ヒントさえあれば、私はその情報を入手します。

前もって感謝します。

PS:私はこの質問がある種の漠然としたものであることを知っています。Googleにはこのような質問がたくさんあり、実際の回答がないので、LMGFYの質問ではないので、Rush -1投票はしないでください。

[〜#〜]更新[〜#〜]

this チュートリアルを使用して、Android using Android studioを使用して、opencvをビルドできましたが、それでも使用方法がわかりませんC#スクリプトによるOpenCVたとえば、cv :: Matの作成方法は?

だから私がどうにかして:

  • OpenCVをビルドし、Android studio(so Javaから)を使用して)いくつかのネイティブコードを実行します。
  • nityネイティブの例 (1つのC関数)をビルドし、C#スクリプトから呼び出します。

しかし、OpenCVの依存関係を含むC++コードを作成して、C#スクリプトからこのコードを呼び出す方法はまだわかりません。

11
Pierre Baret

だから私はようやくそれをうまく動かすことができました!!!!!!!!!! =)

私はそれが私のために働いた方法をここに投稿しています。だから私が何とかしてできたのは、Visual StudioでOpenCVにリンクした.so C++ライブラリをビルドすることです。このライブラリをUnityにインポートし、.soライブラリで定義された非常にシンプルなAndroidアプリケーション呼び出し関数をビルドします。 Androidスマートフォンでアプリを実行します。

使用構成:

  • Unity 2017.2.0f2
  • Visual Studio 2017
  • Android向けOpenCV 3.3.1。 opencv-3.3.1-Android-sdk.ZipOpenCV Webサイト からダウンロードできます。
  • Androidスマートフォン:Lenovo Phab 2 Pro(Google Tango Phone)およびHTC 10でテスト済み

ここで説明する手順は私にとってはうまくいきましたが、Androidデバイスに別のCPUを使用している場合は異なる場合があります(たとえば、ARMではなくARM64用にビルドする必要があります。しかし、実際には、これらの手順は単なる例です)。

私はすでにAndroid SDK、NDK、Unityがコンピューターにインストールされており、UnityでAndroidアプリをすでにビルドできると想定しています。

ステップ1:Visual Studio 2017でC++ Androidライブラリを作成します。

  • ファイル>新規>プロジェクト

左側のドロップダウンメニューから、[テンプレート]> [Visual C++]> [クロスプラットフォーム]> [Android]に移動し、[ダイナミック共有ライブラリ(Android)]を選択します。 (VS2017でAndroid用にビルドできるVSツールをインストールする必要がある場合があります)。この例では、デフォルトの「SharedObject1」名を使用します。

New Project Selection

[ソリューションプラットフォーム]([デバッグ/リリース]ドロップダウンの横)で[ARM]を選択します。リリースでビルドすることをお勧めしますが、ワークフローはまったく同じなので、ここではデバッグのままにします。

enter image description here

ステップ2:このC++ AndroidプロジェクトをOpenCV for Androidにリンクします。

  • opencv-3.3.1-Android-sdk.Zipを好きな場所に抽出します(この場所にファイルを保持する必要があるため、場所を選択して覚えておいてください)。 「apk」、「samples」、「sdk」という3つのサブフォルダーを持つフォルダーが必要です。
  • Visual Studioで、[プロジェクト]> [SharedObject1プロパティ]に移動します。構成で[すべての構成]を選択し(デバッグとリリースの両方に適用されます)、プラットフォームで[ARM]を選択します。次に:
    • C/C++で、OpenCVのインクルードへのフルパスを「追加のインクルードディレクトリ」に追加します。このパスは、C:\ Path-to-OpenCV-Android-sdk\sdk\native\jni\includeです。
    • [リンカー]> [全般]で、OpenCVのライブラリへのフルパスを[追加のライブラリディレクトリ]に追加します。このパスは、C:\ Path-to-OpenCV-Android-sdk\sdk\native\libs\armeabi-v7aです。
    • リンカー>入力で、OpenCVのライブラリファイルへのフルパスを「追加の依存関係」に追加します。このパスは、C:\ Path-to-OpenCV-Android-sdk\sdk\native\libs\armeabi-v7a\libopencv_Java3.soです。

設定方法がわかっている場合は、フルパスの代わりに環境変数を使用できます。ここでは説明しません。

ステップ3:ライブラリのC++/OpenCVコードを記述してビルドする時間

ShareObject1.h

extern "C"
{
    namespace SharedObject1
    {
        float Foopluginmethod();
    }
}

ShareObject1.cpp

#include "SharedObject1.h"
#include <opencv2\core.hpp> // use OpenCV in this C++ Android Library

extern "C" 
{
    float SharedObject1::Foopluginmethod()
    {
        cv::Mat img(10,10,CV_8UC1); // use some OpenCV objects
        return img.rows * 1.0f;     // should return 10.0f
    }
}

次に、ライブラリをビルドします:ビルド>ソリューションのビルド。 「ファイルが見つかりませんblablabla」などのエラーが発生した場合は、STEP 2にフルパスを配置していることを確認するか、環境変数を確認してください。他にエラーがある場合はわかりません。コメントでお尋ねください。

これにより、Path-to-your-VS-Project\SharedObject1\ARM\Debug(またはRelease)の下にlibSharedObject1.soファイルが生成されます。

ステップ4:Unityに行きましょう

  • 新しいUnityプロジェクトを作成し、好きな名前を付けます。
  • 新しいシーンを作成して保存します。
  • ファイル>ビルド設定。 [プラットフォーム]でAndroidを選択し、[プラットフォームの切り替え]をクリックします。
  • プレイヤー設定をクリックします。 [その他の設定]で、パッケージ名を現在の感じに変更します(Unityはデフォルト値が好きではありません)。デバイスフィルターに「ARMv7」を選択します。
  • ビルドにシーンを追加します。

シーンで、メインカメラを選択し、それに「CallNativeCode」という名前の新しいC#スクリプトを追加します。「コンポーネントの追加」>「CallNativeCode」と入力>新しいスクリプト>作成して追加。インスペクタの[フラグをクリア]で[無地]を選択し、暗い色を付けます(これは簡単なデモ用です)。

CallNativeCode.cs

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class CallNativeCode : MonoBehaviour
{    
    [DllImport("SharedObject1")]
    private static extern float Foopluginmethod();

    void OnGUI ()
    {
        // This Line should display "Foopluginmethod: 10"
        GUI.Label(new Rect(15, 125, 450, 100), "Foopluginmethod: " + Foopluginmethod());
    }
}

Assetsフォルダーの下に、「Plugins」という名前のサブフォルダー(スペルは重要です)を作成し、Pluginsの下に「Android」という名前の別のサブフォルダーを作成します。このフォルダーに、ファイルlibSharedObject1.soおよびlibopencv_Java3.soをコピーします(これら2つのファイルへのパスはステップ2にあり、 3)。だからあなたはそのようなものを持つべきです: Unity Editor

UnityエディターでlibSharedObject1.soを選択し、インスペクターでプラグインの選択されたプラットフォームでAndroidのみがチェックされていること、およびCPUがARMv7であることを確認します。 libopencv_Java3.soについても同じようにします。

これで、アプリを電話でビルドして実行でき、お楽しみいただけます! ;-)

したがって、これはダミーのアプリケーションですが、正しいフレーズが表示され、機能します!!! =)これは、Android UnityアプリがOpenCV C++コードを呼び出すことができたことを意味します。より複雑なOpenCV C++コードに関しては、まあ、これはここでのトピックではありません。あなたの創造性を流すときです。

ScreenShot of what you should have

16
Pierre Baret

これは単にピエールの答えを追加するためです。コメントしたかったのですが、十分な評判がありません。私はOpenCV(4.0.1)の最新バージョンを使用して彼の回答を追跡しましたが、実行する必要があるいくつかの追加の作業がありました。

まず、インポートを#include <opencv2/opencv.hpp>に置き換えます。他のインポート文は古いコードを指しています。

次に、プロジェクトのプロパティに移動し、C/C++-> Languageを選択します。言語標準をC++ 11に設定し、「実行時の型情報を有効にする」を「はい」に設定します。

次に、コード生成に移動し、「C++例外を有効にする」を「はい」に設定します。

その後、すべての準備が整います。

3
Ninjaman494