2013-04-25 11 views
6

Meine Kamera-App verarbeitet rohe Kamerabilder von onPreviewFrame() mit OpenCV und zeigt sie dann auf dem Bildschirm an. Die rohen Bilder sind jedoch so orientiert, wie die Kamera am Telefon angebracht ist, was normalerweise nicht richtig ist. Um das zu beheben, drehe ich sie manuell mit OpenCV, was zeitaufwendig ist.Raw-Kameradaten richtig ausrichten

Ich habe in schaute setDisplayOrientation verwenden, aber die Dokumentation besagt, dass

Dies ist nicht die Reihenfolge der Byte-Array in onPreviewFrame weitergegeben beeinflusst

und ich brauche die Daten zu tatsächlich sein mit der rechten Seite nach oben, nicht nur mit der rechten Seite nach oben. Wie kann ich die rohen Kameradaten korrekt ausrichten? Wenn das nicht möglich ist, kann ich das Byte-Array, das mir in onPreviewFrame() übergeben wurde, effizient rotieren, sagen wir OpenGL?

Antwort

3

Kein erreichen könnte, gibt es keine Möglichkeit, die API zu erhalten, dies für Sie zu tun, sondern um herauszufinden, wie Sie die Daten drehen müssen, nehmen Ein Blick auf den Beispielcode unter Camera.Parameters.setRotation. Während sich setRotation() nur auf JPEGs auswirkt, möchten Sie den Daten, die Sie in onPreviewFrame() erhalten, genau die gleiche Menge an Drehung zuweisen wie den JPEGs.

den Beispielcode Reproducing hier, mit geringfügigen Änderungen:

public void onOrientationChanged(int orientation) { 
    if (orientation == ORIENTATION_UNKNOWN) return; 
    android.hardware.Camera.CameraInfo info = 
     new android.hardware.Camera.CameraInfo(); 
    android.hardware.Camera.getCameraInfo(cameraId, info); 
    orientation = (orientation + 45)/90 * 90; 
    int rotation = 0; 
    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { 
     rotation = (info.orientation - orientation + 360) % 360; 
    } else { // back-facing camera 
     rotation = (info.orientation + orientation) % 360; 
    } 
    mCameraOrientation = rotation; // Store rotation for later use 
} 

... 

void onPreviewFrame(byte[] data, Camera camera) { 
    switch(mCameraOrientation) { 
     case 0: 
      // data is correctly rotated 
      break; 
     case 90: 
      // rotate data by 90 degrees clockwise 
     case 180: 
      // rotate data upside down 
     case 270: 
      // rotate data by 90 degrees counterclockwise 
    } 
} 

Sie müssen also von OrientationEventListener erben und wie oben außer Kraft setzen onOrientationChanged, und verwenden Sie dann den berechneten Orientierungswert von dort die Bilder in der Vorschau zu drehen, wenn sie kommen.

1

setDisplayOrientation dreht nur die Kamera gegen die Oberfläche, in die Sie zeichnen, wenn ich mich richtig erinnere. Ich glaube, die Kamera Interpretation drehen wollen, was können Sie mit setRotation

+1

Ich habe das schon gesehen, aber es sagt 'Dies betrifft die Bilder von JPEG Camera.PictureCallback zurückgegeben.' Rotiert es die Rohdaten, auch wenn Sie diesen Rückruf nicht verwenden? –

+0

Die Rohdaten können nicht manipuliert werden, da es genau das ist, was der Sensor "sieht". Ich glaube, es schreibt einfach das entsprechende Exif-Tag in das JPEG. Aber openCV sollte in der Lage sein, Exif zu lesen, es ändert dann die Koordinaten, wenn ich es in die Matte kopiere, glaube ich. – sschrass

+0

Wenn ich 'onPreviewFrame()' verwende, werden die rohen YUV-Daten in ein Byte-Array abgelegt. Es gibt keine Konvertierung zu JPEG und ich mache kein Bild. Es scheint also nicht so, als würde diese Lösung für mich funktionieren. –