2012-10-31 6 views
9

Ich versuche, eine perspektivische Transformation auf einer Bitmap zu machen, die ich über die Kamera aufnehme. Der Benutzer passt einen Begrenzungsviereck (wie durch das weiße Feld dargestellt) um ein rechteckiges Objekt an. Ich versuche dann dieses auf ein rechteckiges Bild zu transformieren, unter Verwendung des Codes:Eine perspektivische Transformation des Bildes auf Android zuschneiden

public static Bitmap perspectiveTransformation(Bitmap bitmap,BoundingQuad boundingQuad) 
{ 
    Matrix matrix = new Matrix(); 
    float[] dst = new float[] { 
      0, 
      0, 
      bitmap.getWidth(), 
      0, 
      bitmap.getWidth(), 
      bitmap.getHeight(), 
      0, 
      bitmap.getHeight() 
    }; 
    float[] src = new float[] { 
      boundingQuad.topLeft.x, 
      boundingQuad.topLeft.y, 
      boundingQuad.topRight.x, 
      boundingQuad.topRight.y, 
      boundingQuad.bottomRight.x, 
      boundingQuad.bottomRight.y, 
      boundingQuad.bottomLeft.x, 
      boundingQuad.bottomLeft.y 
    }; 
    matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); 
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
} 

jedoch meine resultierende Bild enthält Bilddaten, die außerhalb der Grenze meiner quad ist. Dies wäre akzeptabel, wenn ich herausfinden könnte, wie die Koordinaten des Quads nach der Transformation sind, damit ich das Ergebnis zuschneiden kann, aber ich habe absolut keine Ahnung, wie das geht.

Jede Hilfe wäre sehr hilfreich, entweder die Koordinaten des Quadrates nach der Transformation zu finden oder im Idealfall einen Weg zu finden, um zu verhindern, dass diese Situation überhaupt auftritt.

Eingang:

http://i.stack.imgur.com/33RfN.png

Ausgang:

http://i.stack.imgur.com/zWFvA.png

+0

haben Sie eine Lösung zu finden? Ich habe das gleiche Problem. –

+0

@ romain-guy vielleicht hast du einen Hinweis auf dieses Problem? –

Antwort

-2

Nachdem Sie Ihren neuen Bitmap Bild erstellen, können Sie rufen Android in crop Funktionalität gebaut durch den Bau einer 'Ernte' Absicht und Aufrufen, Beispiel:

Intent cropIntent = new Intent("com.android.camera.action.CROP"); 

// Put in 'Extras' here to build the intent 

// Start the activity. It will be handled by returning data to onActivityResult 
startActivityForResult(cropIntent, PIC_CROP); // PIC_CROP is just an arbitrary tag name. 

Weitere Details zum Bildbeschnitt in Android können von here erreicht werden.

Sie werden auch die folgenden in Ihrer App-Manifest-Datei für diese Arbeit hinzufügen müssen:

<uses-feature android:name="android.hardware.camera" ></uses-feature> 
<uses-permission android:name="android.permission.CAMERA" /> 
3

Ich hatte das gleiche Problem und löste es, indem die Koordinaten des Rechtecks ​​nach der Transformation zu finden.

Um diese Koordinaten zu finden, müssen Sie verstehen, was vor sich geht. Die Matrix definiert eine perspektivische Transformation, die durch die 4 Kantenpunkte des Quads und die entsprechenden Punkte gegeben ist. Sie haben dies mit dem folgenden Code getan:

Matrix matrix = new Matrix(); 
float[] dst = new float[] { 
     0, 
     0, 
     bitmap.getWidth(), 
     0, 
     bitmap.getWidth(), 
     bitmap.getHeight(), 
     0, 
     bitmap.getHeight() 
}; 
float[] src = new float[] { 
     boundingQuad.topLeft.x, 
     boundingQuad.topLeft.y, 
     boundingQuad.topRight.x, 
     boundingQuad.topRight.y, 
     boundingQuad.bottomRight.x, 
     boundingQuad.bottomRight.y, 
     boundingQuad.bottomLeft.x, 
     boundingQuad.bottomLeft.y 
}; 
matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); 

Diese Mittel (zum Beispiel), dass der obere linke Punkt Ihres Quad auf den Punkt umgewandelt wird (0,0). Sie können dies überprüfen, indem Sie die Matrix auf die Punkte anwenden und die resultierenden Werte überprüfen. Um die Matrix anzuwenden, können Sie die Methode mapPoints(...) verwenden. Die definierte Transformationsmatrix funktioniert einwandfrei. Die (auf den ersten Blick) seltsame Verhalten dieser Transformation ergibt sich aus der Schaffung der Bitmap:

return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 

Das resultierende Bitmap scheint falsch zu sein, weil einige Punkte (zum Beispiel alle Punkte links von oben- linker Punkt des Quads) werden in negative Koordinaten umgewandelt und wenn Sie etwas in eine Bitmap zeichnen wollen, müssen die Koordinaten positiv sein. Aus diesem Grund sind die transformierten Punkte verschoben und das führt zu merkwürdigen Koordinaten der transformierten Punkte in der Bitmap.

Zum Schluss: Die Punkte werden korrekt in die neuen Koordinaten transformiert, können aber nicht angezeigt werden und sind deshalb verschoben und die verschobenen Koordinaten der transformierten Punkte in der Bitmap sind nicht die Koordinaten, die in den Koordinaten definiert sind Transformationsmatrix.

Um dieses Problem zu lösen und die richtigen Koordinaten der transformierten Punkte in der Bitmap zu erhalten, müssen Sie die Werte der Verschiebung berechnen. Die Verschiebung besteht aus einem x-Wert und einem y-Wert.

Um den x-Wert zu berechnen, transformierte ich den x-Wert des oberen linken Punktes und den x-Wert des unteren linken Punktes des Originalbildes mit der zuvor definierten Matrix. Entweder der obere linke Punkt oder der linke untere Punkt wird in die linke Grenze der resultierenden Bitmap transformiert, und deshalb ist der x-Wert der Bitmap-Koordinate dieses Punktes gleich 0 und der negierte (weil die x- Wert muss positiv sein) x-Wert der transformierten Koordinaten ist der x-Wert der Verschiebung. Der Punkt, der zur linken Grenze der resultierenden Bitmap transformiert wird, ist der Punkt mit dem maximalen negierten x-Wert. Daher ist der x-Wert der Verschiebung das Maximum der negierten x-Werte des transformierten oberen linken und unteren linken Punktes.

Um den y-Wert zu berechnen, habe ich den y-Wert des oberen linken Punktes und den y-Wert des oberen rechten Punktes des Originalbildes transformiert, weil dies die möglichen Punkte sind, die nach oben transformiert werden Grenze der resultierenden Bitmap und der y-Wert des transformierten Punktes ist gleich 0 in der resultierenden Bitmap. Indem Sie das Maximum der negierten Werte der transformierten y-Werte wieder aufnehmen, erhalten Sie den y-Wert der Verschiebung.

Der resultierende Code sieht wie folgt aus:

float[] mappedTL = new float[] { 0, 0 }; 
    matrix.mapPoints(mappedTL); 
    int maptlx = Math.round(mappedTL[0]); 
    int maptly = Math.round(mappedTL[1]); 

    float[] mappedTR = new float[] { bitmap.getWidth(), 0 }; 
    matrix.mapPoints(mappedTR); 
    int maptrx = Math.round(mappedTR[0]); 
    int maptry = Math.round(mappedTR[1]); 

    float[] mappedLL = new float[] { 0, bitmap.getHeight() }; 
    matrix.mapPoints(mappedLL); 
    int mapllx = Math.round(mappedLL[0]); 
    int maplly = Math.round(mappedLL[1]); 

    int shiftX = Math.max(-maptlx, -mapllx); 
    int shiftY = Math.max(-maptry, -maptly); 

    Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
    return Bitmap.createBitmap(resultBitmap, shiftX, shiftY, bitmap.getWidth(), bitmap.getHeight(), null, true); 
Verwandte Themen