2012-10-31 19 views
9

私はカメラでキャプチャしたビットマップに対して透視変換を実行しようとしています。ユーザは、四角形のオブジェクトの周りに四角形(白いボックスで示されるように)を調整する。私の結果として得られるイメージが私のクワッドの境界の外側にある画像データが含まれていますが視点をトリミングしてAndroid上で画像を変換する

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

:私は、以下のコードを使用して矩形画像にこれを変換しようとします。もし私が結果を切り抜くことができるように変換後に四角形の座標が何であるかを知ることができれば、これは受け入れられるだろうが、私はそれをどうするか全く考えていない。

変換後のクワッドの座標を見つけるか、最初にこのような状況が発生しないように理想的な方法を見つけるのに役立ちます。

入力:

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

出力:

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

+0

はあなたが解決策を見つけましたか?私は同じ問題があります。 –

+0

@ romain-guy多分あなたはその問題のヒントを持っていますか? –

答えて

-2

あなたの新しいBitmapイメージを作成した後、あなたが呼び出すことができますAndroidの '収穫' の意図を構築することにより、作物の機能に建てられ、それを呼び出す例:

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. 

Androidでの画像クロップに関する詳細は、hereから取得できます。

また仕事に、このため、アプリケーションのマニフェストファイルに以下を追加する必要があります。

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

私は同じ問題を抱えていたし、変換後の四角形の座標を見つけることによってそれを解決しました。

これらの座標を見つけるには、何が起こっているのかを理解する必要があります。 この行列は、クワッドの4つのエッジポイントと対応するポイントによって与えられる透視変換を定義します。次のコードでこれを行っている:

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

この手段(例えば)あなたのクワッドの左上の点を点(0,0)に変換されていること。これを確認するには、行列をポイントに適用し、結果の値をチェックします。行列を適用するには、メソッドmapPoints(...)を使用します。定義された変換行列は正常に動作します。ビットマップの作成から、この変換結果の(一見)奇妙な振る舞いは:

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

結果のビットマップは、間違っているようですので、トップの左にあるいくつかの点(例えば、すべてのポイント四角形の左の点)が負の座標に変換され、ビットマップに何かを描画したい場合は、座標は正でなければなりません。このため、変換された点はシフトされ、ビットマップ内の変換された点の変な座標につながります。

結論:ポイントは新しい座標に正しく変換されますが表示することはできません。そのため、シフトされ、ビットマップ内の変換されたポイントのシフトされた座標は座標で定義されていません。変換マトリックス。

この問題を解決し、ビットマップ内の変換された点の適切な座標を取得するには、シフトの値を計算する必要があります。シフトはx値とy値で構成されます。

x値を計算するために、元の画像の左上点のx値と元の画像の左下点のx値を、前に定義した行列で変換しました。左上の点または左下の点のいずれかが結果のビットマップの左境界に変換され、このため、この点のビットマップ座標のx値は0に等しく、ネガティブ(x座標はゼロであるため、値は正の値でなければなりません)変換された座標のx値はシフトのx値です。結果のビットマップの左境界に変換されるポイントは、最大のネゲートされたx値を持つポイントです。したがって、シフトのx値は、変換された左上および左下点の無効化されたx値の最大値です。

y値を計算するために、Iは元の画像の右上の点のy値とy値を変換しました。これは元の画像の頂点に変換される可能な点であるためです結果のビットマップの境界と変換された点のy値は、結果のビットマップでは0に等しくなります。変換されたy値のネゲートされた値の最大値を再び取ることによって、シフトのy値が得られます。

結果のコードは次のようになります。

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); 
関連する問題