2012-02-11 61 views
4

我正在開發一個應用程序,其中有一個圖像變形模塊。我提到了幾個網站,但無法獲得任何解決方案,可以解決我的問題。如何在Android中變形圖像?

面部扭曲的任何教程/鏈接或建議將有所幫助。

+1

號那這個網站不是如何工作的。如果您遇到特定問題,我們會盡力幫助解決問題。你必須自己做一些工作。 – 2012-02-11 04:57:52

+5

我相信人們可以要求教程等,它的幫助視域,他們正在尋求相關的幫助,所以它應該被允許 – FabianCook 2012-02-11 05:14:30

+1

現在編輯的問題是允許在SO,我想... – 2012-02-11 05:24:28

回答

9

這是來自Android SDK附帶的示例。從你的問題,如果你想知道Android的API或非常規整算法

public class BitmapMesh extends GraphicsActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(new SampleView(this)); 
    } 

    private static class SampleView extends View { 
     private static final int WIDTH = 20; 
     private static final int HEIGHT = 20; 
     private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); 

     private final Bitmap mBitmap; 
     private final float[] mVerts = new float[COUNT*2]; 
     private final float[] mOrig = new float[COUNT*2]; 

     private final Matrix mMatrix = new Matrix(); 
     private final Matrix mInverse = new Matrix(); 

     private static void setXY(float[] array, int index, float x, float y) { 
      array[index*2 + 0] = x; 
      array[index*2 + 1] = y; 
     } 

     public SampleView(Context context) { 
      super(context); 
      setFocusable(true); 

      mBitmap = BitmapFactory.decodeResource(getResources(), 
                R.drawable.beach); 

      float w = mBitmap.getWidth(); 
      float h = mBitmap.getHeight(); 
      // construct our mesh 
      int index = 0; 
      for (int y = 0; y <= HEIGHT; y++) { 
       float fy = h * y/HEIGHT; 
       for (int x = 0; x <= WIDTH; x++) { 
        float fx = w * x/WIDTH;      
        setXY(mVerts, index, fx, fy); 
        setXY(mOrig, index, fx, fy); 
        index += 1; 
       } 
      } 

      mMatrix.setTranslate(10, 10); 
      mMatrix.invert(mInverse); 
     } 

     @Override protected void onDraw(Canvas canvas) { 
      canvas.drawColor(0xFFCCCCCC); 

      canvas.concat(mMatrix); 
      canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, 
            null, 0, null); 
     } 

     private void warp(float cx, float cy) { 
      final float K = 10000; 
      float[] src = mOrig; 
      float[] dst = mVerts; 
      for (int i = 0; i < COUNT*2; i += 2) { 
       float x = src[i+0]; 
       float y = src[i+1]; 
       float dx = cx - x; 
       float dy = cy - y; 
       float dd = dx*dx + dy*dy; 
       float d = FloatMath.sqrt(dd); 
       float pull = K/(dd + 0.000001f); 

       pull /= (d + 0.000001f); 
      // android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull); 

       if (pull >= 1) { 
        dst[i+0] = cx; 
        dst[i+1] = cy; 
       } else { 
        dst[i+0] = x + dx * pull; 
        dst[i+1] = y + dy * pull; 
       } 
      } 
     } 

     private int mLastWarpX = -9999; // don't match a touch coordinate 
     private int mLastWarpY; 

     @Override public boolean onTouchEvent(MotionEvent event) { 
      float[] pt = { event.getX(), event.getY() }; 
      mInverse.mapPoints(pt); 

      int x = (int)pt[0]; 
      int y = (int)pt[1]; 
      if (mLastWarpX != x || mLastWarpY != y) { 
       mLastWarpX = x; 
       mLastWarpY = y; 
       warp(pt[0], pt[1]); 
       invalidate(); 
      } 
      return true; 
     } 
    } 
} 
2

圖像變形一般由兩個主要階段,目前尚不清楚。在第一階段中,您會查找每張圖片上匹配的點。第二階段涉及在一組匹配點之間尋找轉換。這兩個階段都不是微不足道的,圖像扭曲(一般來說)仍然是一個難題。我不得不在過去解決這個問題,所以可以從經驗中講出來。

通過將問題分爲兩部分,您可以獨立設計每個零件的解決方案。例如,閱讀網絡上的一些資料,例如http://groups.csail.mit.edu/graphics/classes/CompPhoto06/html/lecturenotes/14_WarpMorph_6.pdf會很有幫助。

在第一階段,互相關經常用作在兩張圖像上找到匹配點的基礎。

在第二階段中使用的轉換將決定如何準確地將一幅圖像轉換爲另一幅圖像。線性變換現在會非常好,而使用樣條逼近的二維變換必然會解決非線性問題。

這裏是另一個有用link