2017-09-26 48 views
3

我有一个小小的疑问,我希望你能解决它。基于本地OpenCV的统一Android应用程序

我想创建一个统一的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; 

}} 
+0

'imgData = new byte [width * height * 4];'你为什么乘以4?您的相机是否提供4声道图像? – zindarod

+1

因为是RGB图像,我试过把3个通道蝙蝠失败。所以我把4个频道 –

+1

'RGB'意味着3个频道。如果你的代码失败了,那是因为其他原因。正如@uelordi建议的,尝试使用Java本地代码捕获图像,使用OpenCV仅处理图像。 – zindarod

回答

2

如果您已经托管你的整个代码在GitHub上,或者您可以创建一个要点可能会更好。

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

我会尽力列举为什么会发生这种情况。

  • 首先,OpenCV的视频采集类camera.open(0)无ffmpeg的不工作(不容易crosscompile对Android原生)。

    • 如果要使用本机摄像头在C++从Android和你需要使用最新的NDK与API 24
  • 我看到你正在使用WebCamTexture类从统一,但几乎可能这个抓取的纹理是空的,因此你会看到图像中的黑色屏幕。

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

如果这不起作用,你可以有什么办法可以粘贴Java代码统一的项目?因为在java中捕捉相机非常容易。 希望这些线索可以帮助你。

Ondo izan eta animo。

Unai。

1

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

。您使用COLOR_BGR2RGB在C++ side.That因为你在C#侧使用TextureFormat.RGB24COLOR_BGR2BGRA

。如果要修改C++插件中的C#数组,必须将其固定在内存中。修改后,您可以取消固定它。如果你不这样做,你会遇到一个会让你永远找不到的bug。

使用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); 
} 

。最后,这是可选的,但您可能需要使用Java来读取来自摄像头的图像,然后通过用C++将图像转换为OpenCV。我见过很多人使用OpenCV从相机读取时遇到问题,更不用说它也很慢。

相关问题