OpenCV + Android + Unity

OpenCV + Android + Unity

我正在寻找一种在 Unity 项目中使用 OpenCV 的方法,我的目标平台是 Android 设备。

我知道 Unity 资产商店中存在一些资产,但我不想使用它们,因为我发现它们太贵了。

我设法在 Unity 中使用 opencv 作为 C++ 本机插件,方法是使用 this 教程在 dll 中预编译 OpenCV,但 dll 意味着 Windows 桌面,所以它对我构建没有太大帮助我的 Android.

项目

我还找到了 opencv jar 存档,我知道它们可以很容易地导入到 Unity 中,但我不知道下一步该怎么做:那就是如何从 Unity C# 脚本访问 OpenCV 的东西。

因此,如果有人知道如何在 Unity 编辑器中使用 OpenCV 配置虚拟 hello world 项目以构建到 Android,或者甚至有提示,我会获取任何相关信息。

提前致谢。

PS:我知道这个问题有点含糊,相信我,这不是 LMGFY 问题,因为 google 有很多这样的问题,但没有真正的答案,所以请不要急 -1 票。

更新

使用 this 教程,我设法使用 Android studio 为 Android 构建了 opencv,但我仍然不知道如何从 C# 脚本中使用 OpenCV。比如如何创建一个cv::Mat?

所以我设法做到了:

但我仍然无法弄清楚如何使用 OpenCV 依赖项构建一些 C++ 代码并从 C# 脚本调用此代码。

所以我终于成功了!!!!!!!!!!! =)

我在这里发布它对我有用的方式。所以我设法做的是用 link 构建一个 .so C++ 库到 Visual Studio 的 OpenCV。在 Unity 中导入此库并构建一个非常简单的 Android 应用程序调用函数,定义在 .so 库中。 运行 Android phone 上的应用程序。

使用的配置:

  • 统一 2017.2.0f2
  • Visual Studio 2017
  • 用于 Android 的 OpenCV 3.3.1。 opencv-3.3.1-android-sdk.zip 可从 OpenCV website.
  • 下载
  • Android smartphone : 在 Lenovo Phab 2 Pro (Google Tango Phone) 和 HTC 10
  • 上测试

请注意,我将描述的步骤对我有用,但如果您的 Android 设备上有不同的 CPU,它可能对您有所不同(您必须为 ARM64 构建例如 ARM,但事实是这些步骤只是一个示例)。

我假设您已经在计算机上安装了 Android SDK、NDK 和 Unity,因此您已经能够使用 Unity 构建 android 应用程序。

第 1 步:使用 visual Studio 2017.

创建一个 C++ Android 库
  • 文件 > 新建 > 项目

从左侧的下拉菜单转到模板 > Visual C++ > 跨平台 > Android 和 select "Dynamic Shared Library (Android)"。 (您可能必须安装能够使用 VS2017 为 Android 构建的 VS 工具)。我将保留此示例的默认 "SharedObject1" 名称。

在 "Solution platform"(在 Debug/Release 下拉列表旁边)select "ARM"。我建议您在发布时构建,但在这里我们将坚持调试,因为工作流程完全相同。

第 2 步:Link 这个 C++ Android OpenCV 项目 Android.

  • 提取 opencv-3.3.1-android-sdk.zip 任何你想要的地方(选择并记住这个地方,因为你需要保留这个地方的文件)。您应该有一个包含 3 个子文件夹的文件夹,分别名为 "apk"、"samples" 和 "sdk".
  • 在 Visual Studio 中,转到“项目”>“SharedObject1 属性”。在配置中选择 "All configurations"(因此它适用于 Debug 和 Release),平台选择 "ARM"。然后:
    • 在 C/C++ 下,将 OpenCV 包含的完整路径添加到 "Additional Include Directories"。这个路径是:C:\Path-to-OpenCV-android-sdk\sdk\native\jni\include.
    • 在 Linker > General 下,将 OpenCV 库的完整路径添加到 "Additional Library Directories"。这个路径是:C:\Path-to-OpenCV-android-sdk\sdk\native\libs\armeabi-v7a.
    • 在 Linker > Input 下,将 OpenCV 库文件的完整路径添加到 "Additional Dependencies"。这个路径是: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
    }
}

然后构建库:构建 > 构建解决方案。如果您在此处遇到 "Files not found blablabla" 之类的错误,请检查您是否在步骤 2 中输入了完整路径或检查您的环境变量。如果还有其他错误,我不知道,在评论中提问。

这应该在Path-to-your-VS-Project\SharedObject1\ARM\Debug(或Release)下生成了一个libSharedObject1.so文件。

第 4 步:让我们转到 Unity

  • 创建一个新的 Unity 项目并根据需要命名。
  • 创建一个新场景并保存。
  • 文件 > 构建设置。在平台 select Android 下点击 "Switch Plateform".
  • 点击播放器设置。在 "Other Settings" 下,将 Package Name 更改为您目前的感觉(Unity 不喜欢默认值)。 Select "ARMv7" 用于设备过滤器。
  • 将您的场景添加到构建中。

在您的场景中,select 主摄像机并向其添加名为 "CallNativeCode" 的新 C# 脚本:"Add Component" > 键入 "CallNativeCode" > 新脚本 > 创建并添加。在检查器中,在 Clear Flags 中选择 "Solid color" 并放置深色(这只是为了快速演示)。

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.solibopencv_java3.so(这两个文件的路径在步骤 2 和3).所以你应该有这样的东西:

Select libSharedObject1.so 在 Unity Editor 中并在检查器中检查插件的 Selected 平台是否只有 Android 检查,CPU 是 ARMv7。对 libopencv_java3.so.

做同样的事情

现在您可以在 phone 上构建和 运行 您的应用程序,尽情享受吧! ;-)

所以这只是一个虚拟应用程序,但它显示了正确的短语,它有效!!! =) 这意味着我们设法让 Android Unity 应用程序调用 OpenCV C++ 代码。关于更复杂的OpenCV C++代码,好吧,这不是主题,是时候发挥你的创造力了。

这只是为了补充 Pierre 的回答,我想发表评论,但我没有足够的声誉。我使用最新版本的 OpenCV(4.0.1) 按照他的回答进行操作,我还需要做一些额外的事情。

首先,将导入替换为 #include <opencv2/opencv.hpp>。另一个导入语句指向旧代码。

然后转到项目的属性和select C/C++->语言。设置语言标准为C++11,设置Enable 运行-Time Type Information为yes。

然后转到代码生成并将启用 C++ 异常设置为是。

在那之后,你应该一切就绪。

只是为了分享我在 Visual Studio.

中使用 C++17 和 OpenCV 4.1.0 编译 .so 所必须做的事情

首先,我必须通过 VS-Installer 将我的 AndroidNDK 更新到 n15c。使用单独下载的 NDK 对我不起作用。开始构建时,将打印 NDK_ROOT 以便您检查它是否设置正确。

按照 Pierre 的步骤 1 和 2 进行操作。 在Linker->Input中,我只在"Library Dependencies"中设置了库名。我的情况是 opencv_java4,这是链接器喜欢的方式,源自 libopencv_java4.so

在选项卡 常规 中设置:

  • 平台工具集:Clang 5.0
  • 配置类型:动态库 (.so)
  • 目标 API:牛轧糖 7.0 (android-24)(其他可能也不错)
  • STL的使用:LLVM libc++共享(c++_shared)

在标签语言中设置:

  • 启用Run-Time信息:真
  • C++ 语言标准:c++17 (-std=c++1z)

在选项卡代码生成中将启用C++异常设置为

在选项卡链接器->命令行中添加-lm -lz

我还必须在 C/C++ -> 预编译 Headers[ 中设置 不使用预编译 Headers =49=]。不过我认为这通常不是必需的。

希望这对某人有所帮助!