2017-09-21 1 views
0

Ich möchte Kamera und Linien zeigen, die ich in Echtzeit entdeckt habe (mit i.MX6 und Android 4.4). Ich benutze die Android-Kamera .addCallbackBuffer, um einen Frame zu erhalten und verwende TextureView, um die Kameravorschau anzuzeigen.Kann ich TextureView verwenden, um die Kameravorschau und die erkannte Zeile gleichzeitig anzuzeigen?

JNI (C++): frame Puffer- erhalten> konvertieren byte [] Mat-> als die Verwendung OpenCV Bildverarbeitung zu tun

JNI kann Mat zurückkehren (verwenden .getNativeObjAddr()), die bereits Linien darauf zeichnen oder geben Sie zwei Koordinaten zurück, die die Start- und Endpunkte der Linie sind

Dieser Code neue Mat in JNI und hoffe, nur zwei Koordinaten zurückgeben. Wenn diese Methode nicht funktioniert, werde ich neue Mat in JAVA und senden .getNativeObjAddr() zu JNI, dann Mat zurückgeben. Zeigen Sie Mat in TextureView?

Frage: Wie Kameravorschau und erkannte Zeile zur gleichen Zeit mit TextureView zeigen?

In MainActivity.java

public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, PreviewCallback { 
protected Camera mCamera; 
private TextureView mTextureView; 
public byte[][] cameraBuffer; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.activity_main); 

    mTextureView = new TextureView(this); 
    mTextureView.setSurfaceTextureListener(this); 
    setContentView(mTextureView); 
} 
.... 
@Override 
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
    mCamera = Camera.open(0); 
    int bufferSize = mCamera.getParameters().getPictureSize().width * mCamera.getParameters().getPictureSize().height 
      * ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8; 
    cameraBuffer = new byte[3][bufferSize]; 

    thread = new getFrameThread(this, kCameraWidth, kCameraHeight); 
    for (int i = 0; i < 3; ++i) 
     mCamera.addCallbackBuffer(cameraBuffer[i]); 

    mCamera.setPreviewCallbackWithBuffer(this);    
    thread.start(); 

    if (mCamera == null) { 
     throw new RuntimeException("Default camera not available"); 
    } 
    try { 
     mCamera.setPreviewTexture(surface); 
     mCamera.startPreview(); 
    } catch (IOException ioe) { 
     // Something bad happened 
    } 
} 

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    // TODO Auto-generated method stub 
    camera.addCallbackBuffer(data);//callback data to cameraBuffer 
    thread.refresh(data, countFrame);//send new frame data to JNI 
} 
.... 
static { 
    System.loadLibrary("opencv_java"); //load opencv_java lib 
    System.loadLibrary("testLib"); 
} 
public native void getRawFrame(byte[] data,int width, int height, int count); 

} 

In getFrameThread (Gewinde JNI-Funktion 'getRawFrame' laufen)

public class getFrameThread extends Thread{ 
    public byte[] data; 
    { 
    ..... 
    mainActivity.getRawFrame(data, 480, 720); 
    ..... 
    } 

    public void refresh(byte[] data, int countFrame){ 
     this.data = data; 
    } 
} 

In JNI

#include <jni.h> 
#include <stdio.h> 
#include <stdlib.h> 

#include <opencv2/opencv.hpp> 
using namespace cv; 

extern"C" 
{ 
..... 
JNIEXPORT void JNICALL Java_com_example_adas_MainActivity_getRawFrame(JNIEnv* env, jobject thisobject, 
    jbyteArray data, jint width, jint height){ 

    int length = env->GetArrayLength(data); 
    unsigned char *bufferIn = (unsigned char*) env->GetPrimitiveArrayCritical(data, NULL); 

    yuvMat = Mat(height * 3/2, width, CV_8UC1, bufferIn); 
    cvtColor(yuvMat, grayMat, cv::COLOR_YUV2GRAY_I420); 


    //Do lines detected 
    ..... 
    env->ReleasePrimitiveArrayCritical(data, bufferIn, JNI_ABORT); 
} 

Antwort

0

Sie die Kamera Live TextureView überlagern Bei einer Bildansicht ist es in Ordnung, wenn dieses Bild teilweise transparent ist. Aber das ist keine gute Lösung für Augmented Reality. Der Grund dafür ist, dass der von OpenCV generierte Inhalt mit Verzögerung geliefert wird. Diese Verzögerung mag nicht sehr signifikant sein, aber sie kann für den Benutzer sehr störend sein.

Das Ergebnis ist viel besser, wenn Sie den Live-Kamerastrom ausblenden und das Bild anzeigen (aus onPreviewFrame()), das durch OpenCV-Verarbeitung geändert wurde. Der auf dem Bildschirm angezeigte AR wird einige Millisekunden verzögert (im Vergleich zur Live-Ansicht der Kamera), aber die Szene stimmt mit den erkannten Linien überein. Ich habe ein gutes Beispiel (und detaillierte Programmieranleitung) in diesem blog post gefunden.

Sie benötigen immer noch die TextureView, da die Android Camera API vorschreibt, dass Sie eine Live-Vorschau haben, um onPreviewFrame() Callbacks zu erhalten. Um dies zu verbergen, können Sie es mit anderen Ansichten überlagern oder die Textur auf der Ebene von OpenGL manipulieren.

Sie können auch OpenGL verwenden, um das Ergebnis von OpenCV anzuzeigen: Oft ist die Leistung eines solchen Arbeitsablaufs viel besser als die Verwendung anderer Möglichkeiten zur Anzeige der Bilder.

Sie können auch OpenGL verwenden, um die Linien - die Ergebnisse der OpenCV-Verarbeitung - nicht in Form von Bitmap zu zeichnen und die Kameravorschau als separate Textur zu verwenden.

+0

Danke, ich werde 'OpenGL versuchen, das Ergebnis von OpenCV' diese Methode anzuzeigen. –

+0

Können Sie mir einen Hinweis oder eine Funktion geben, OpenGL zu verwenden, um das Ergebnis von OpenCV anzuzeigen? Vielen Dank. –

+0

Ich kann [graphika] (https://github.com/google/grafika) als guten Ausgangspunkt empfehlen, um die OpenGL-Beziehung mit der Android-Kamera zu erlernen. Sie können diesen [Artikel] (http://www.anandmuralidhar.com/blog/android/corners/) auch nützlich finden. Es zeigt meinen Hauptpunkt: Die roten Punkte sind auf die richtigen Pixel auf dem Bildschirm gepinnt, auch wenn der ganze Fluss etwas verzögert ist. –

Verwandte Themen