2017-09-26 3 views
3

私はあなたがそれを解決できることを少しは疑問に思います。ネイティブOpenCVをベースにした、単一性のAndroidアプリケーション

私は1つでアンドロイドアプリケーションを作成したいと思います。アプリケーションは、デバイスのカメラを起動し、画面上でそれを表示することから成ります。このために、私は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#の:私は、コードを添付して私を助けることができるあなたはGitHubの上であなたの全体のコードを主催しているか、あなたはその要旨を作成することができればより良いかもしれない場合

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

しかし、私はあなたのカメラのフレームがnullだと思います。

私はこれがなぜ起こるのかを列挙しようとします。

  • まず、ffmpegのないと動作しない(0) OpenCVのビデオキャプチャクラスcamera.openは(アンドロイドネイティブのためにクロスコンパイルすることは容易ではありません)。

    • あなたはアンドロイドからC++でネイティブのカメラを使用したいとあなたがAPIを使用して、最新のNDKを使用する必要がある場合は24
  • 私はあなたがユニティからWebCamTextureクラスを使用していることがわかりますが、ほとんどおそらくこのグラブされたテクスチャは空であり、したがって画像の黒い画面が表示されます。

opencvのユニティプラグインを検索しようとしていますか? 私が見ているだけでは、これは(無料ではない)である。 https://www.assetstore.unity3d.com/en/#!/content/21088

これが動作しない場合は、ユニティ・プロジェクトのためのJavaコードを貼り付けする方法を持っているだろうか? Javaでのカメラキャプチャはとても簡単です。 これらの手がかりがあなたに役立つことを願っています。

オンンドizan eta animo。

Unai。

1

コードを数分間試した後、私はあなたのコードでいくつかの間違いを発見しました。

。あなたは、あなたがC#の側にTextureFormat.RGB24を使用しているので、COLOR_BGR2BGRAする必要がありますC++ side.ThatにCOLOR_BGR2RGBを使用。

。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); 
} 

.Finally、これはオプションですが、あなたが合格カメラから画像を読み取るためのJavaを使用することもできますC++を使ったOpenCVへの画像。私はOpenCVを使ってカメラから読み込むことで多くの人が問題に遭遇するのを見てきました。

関連する問題