【问题标题】:Android application on unity based on native OpenCV基于原生 OpenCV 的 Unity 上的 Android 应用
【发布时间】:2018-03-07 15:59:30
【问题描述】:

我有个小疑问希望你能解决。

我想统一创建一个 android 应用程序。该应用程序包括激活设备的摄像头并在屏幕上查看它。为此,我想基于基于 OpenCV 的原生 C++ 代码。

我有生成的代码,但是当我运行应用程序时,我看到的是场景而不是图像,我有一种感觉,这是因为 OpenCV 的 VideoCapture 功能我没有很好地用于 android。你能帮我附上代码吗:

C++:

__declspec(dllexport) void iniciar(int& widt, int& heigh) {
camera.open(0);
if (!camera.isOpened())
{
    return;
}
widt = (int)camera.get(CV_CAP_PROP_FRAME_WIDTH);
heigh = (int)camera.get(CV_CAP_PROP_FRAME_HEIGHT);
trueRect.x = 5;
trueRect.y = 5;
trueRect.width = 100;
trueRect.height = 100;
midX = 1;
midY = 1;
wi = 0;
he = 0;
}


__declspec(dllexport)
void video(unsigned char* arr) {
Mat frame;
Mat resi;
Mat dst;//dst image
camera >> frame;
if (frame.empty()) {
    return;
}
flip(frame, dst,1);
//resize(dst, resi, Size(width, height));
cv::cvtColor(dst, dst, COLOR_BGR2RGB);
copy(dst.datastart, dst.dataend, arr);
}

C#:

public class camara : MonoBehaviour {

[DllImport("NativoPrincipio")]
public static extern void video(byte[] img);

[DllImport("NativoPrincipio")]
public static extern void iniciar(ref int widt, ref int heigh);

WebCamTexture back;
Texture2D textura;
byte[] imgData;
int width = 0;
int height = 0;


// Use this for initialization
void Start () {
    back = new WebCamTexture();
    //GetComponent<Renderer>().material.mainTexture = back;
    //back.Play();
    iniciar(ref width, ref height);
}

// Update is called once per frame
void Update ()
{
    imgData = new byte[width * height * 4];
    video(imgData);
    textura = new Texture2D(width, height, TextureFormat.RGB24, false);
    textura.LoadRawTextureData(imgData);
    textura.Apply();
    GetComponent<Renderer>().material.mainTexture = textura;
    imgData = null;
    textura = null;

}}

【问题讨论】:

  • imgData = new byte[width * height * 4]; 为什么要乘以 4?您的相机是否提供 4 通道图像?
  • 因为是 RGB 图像,我尝试放置 3 个通道但失败。所以我放了 4 个频道
  • RGB 表示 3 个通道。如果您的代码失败,那是因为其他原因。正如@uelordi 建议的那样,尝试使用Java 本机代码捕获图像,仅使用OpenCV 处理图像。

标签: c# android c++ opencv unity3d


【解决方案1】:

如果您将整个代码托管在 GitHub 上,或者您可以创建一个 gist 会更好。

但是,我认为你的相机框架是空的。

我将尝试列举为什么会发生这种情况。

  • 首先,opencv视频采集类camera.open(0)没有ffmpeg是不行的(android Native不容易交叉编译)。

    • 如果你想在android中使用c++中的原生相机,你需要使用最新的ndk和api 24。
  • 我看到您正在使用 Unity 的 WebCamTexture 类,但这个抓取的纹理几乎可能是空的,因此您会在图像中看到黑屏。

您是否尝试为 opencv 搜索统一插件? 我唯一看到的是这个(不是免费的): https://www.assetstore.unity3d.com/en/#!/content/21088

如果这不起作用,您有什么方法可以粘贴统一项目的 java 代码吗?因为Java中的相机捕捉要容易得多。 希望这些线索对你有所帮助。

Ondo izan eta animo。

乌奈。

【讨论】:

    【解决方案2】:

    盯着你的代码看了几分钟后,我发现你的代码有几个错误。

    1。您在 C++ 端使用了 COLOR_BGR2RGB。应该是 COLOR_BGR2BGRA,因为您在 C# 端使用了TextureFormat.RGB24

    2.如果你想在C++插件中修改一个C#数组,你必须把它固定在内存中。修改后,您可以取消固定它。如果您不这样做,您将遇到一个需要您永远找到的错误。

    使用fixed 关键字固定数组,然后将其转换为IntPtr 并将其作为IntPtr 传递给视频函数。最好同时传入数组大小,这样您就不会使用不存在的索引。

    类似这样的:

    [DllImport("NativoPrincipio")]
    public static extern void video(IntPtr img, int count);
    

    ...

    //Pin Memory
    fixed (byte* p = imgData)
    {
        video((IntPtr)p, imgData.Length);
    }
    

    3。最后,这是可选的,但您可能希望使用 Java 从相机读取图像,然后使用 C++ 将图像传递给 OpenCV。我见过很多人在使用 OpenCV 从相机读取数据时遇到问题,更不用说它也很慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-12
      • 1970-01-01
      • 2014-05-23
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      相关资源
      最近更新 更多