5

Shpere distorsiyon filtresini kullanan bir uygulamayı uygulamaya çalışıyorum. Ben piksel konumunu getPixel() ve setpixel() yöntemleriyle değiştiren here'dan bir algoritma kullanıyorum. Benim sorunum Android cihazlar için çok yavaş ve aynı küre (ve diğerleri) benim yaklaşımından daha hızlı bir şekilde filtre uygulayan uygulamalar var. (örneğin Picsay Pro uygulaması) Hızlı distorsiyon algoritmalarını bulmak veya uygulamak için herhangi bir kişi paylaşabilir veya verebilir. algoritması uygularHızlı görüntü bozulma algoritmaları arıyorsunuz

Güncel filtresi:

public boolean sphereFilter(Bitmap b, boolean bSmoothing) 
{ 
    int nWidth = b.getWidth(); 
    int nHeight = b.getHeight(); 

    Point [][] pt = new Point[nWidth][nHeight]; 
    Point mid = new Point(); 
    mid.x = nWidth/2; 
    mid.y = nHeight/2; 

    double theta, radius; 
    double newX, newY; 

    for (int x = 0; x < nWidth; ++x) 
     for (int y = 0; y < nHeight; ++y) 
     { 
      pt[x][y]= new Point(); 
     } 

    for (int x = 0; x < nWidth; ++x) 
     for (int y = 0; y < nHeight; ++y) 
     { 
      int trueX = x - mid.x; 
      int trueY = y - mid.y; 
      theta = Math.atan2((trueY),(trueX)); 

      radius = Math.sqrt(trueX*trueX + trueY*trueY); 

      double newRadius = radius * radius/(Math.max(mid.x, mid.y)); 

      newX = mid.x + (newRadius * Math.cos(theta)); 

      if (newX > 0 && newX < nWidth) 
      { 
       pt[x][y].x = (int) newX; 
      } 
      else 
      { 
       pt[x][y].x = 0; 
       pt[x][y].y = 0; 
      } 

      newY = mid.y + (newRadius * Math.sin(theta)); 

      if (newY > 0 && newY < nHeight && newX > 0 && newX < nWidth) 
      {     
       pt[x][ y].y = (int) newY; 
      } 
      else 
      { 
       pt[x][y].x = pt[x][y].y = 0; 
      } 
     } 
    offsetFilterAbs(b, pt); 
    return true; 
} 

hesaplanan piksellerin pozisyonları yerine kodu.

public boolean offsetFilterAbs(Bitmap b, Point[][] offset) 
{ 
     int nWidth = b.getWidth(); 
     int nHeight = b.getHeight(); 

     int xOffset, yOffset; 

     for(int y=0;y < nHeight;++y) 
     { 
      for(int x=0; x < nWidth; ++x) 
      { 
       xOffset = offset[x][y].x; 
       yOffset = offset[x][y].y; 

       if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth) 
       { 
        b.setPixel(x, y, b.getPixel(xOffset, yOffset)); 
       }     
      }    
     } 

    return true; 
} 
+0

[Image Warping - Bulge Effect Algorithm] 'ın olası bir kopyası (http://stackoverflow.com/questions/5055625/image-warping-bulge-effect-algorithm) –

+0

Evet, oldukça yinelenir, ancak şunu unutmayın: Bu soruya cevap kabul edildi * burada değil * gerçekten istediğiniz bir şey - istediğiniz ne GLSL shader. –

+0

@BlueRaja, Şu anda bağlantınızdaki ile aynı algoritmayı kullanıyorum ve android cihazlar için hala çok yavaş – Tony

cevap

5

Şu anda zaten linke biriyle aynı algoritmayı kullanıyorum ve hala itibaren android cihazlar

için çok yavaş benim link in the comments above:

 
Given 
r = Sqrt((x - 0.5)^2 + (y - 0.5)^2) 
a = ArcTan2(y - 0.5, x - 0.5) 
n = Bulge factor (default = 1) 

Set 
x' = r^n * Cos(a) + 0.5 
y' = r^n * Sin(a) + 0.5 

(Unutmayın ki, bu denklemde x ve y 0 ile 0 arasında değişir. Boyutlarınız 0'dan w, a bit of math kullanma w/2 ile 0.5)

yerine, biz

 
Cos(a) = Cos(ArcTan2(y - 0.5, x - 0.5)) 
     = (x - 0.5)/r 
Sin(a) = Sin(ArcTan2(y - 0.5, x - 0.5)) 
     = (y - 0.5)/r 

Bu aldığımız beri

 
r = (x - 0.5)^2 + (y - 0.5)^2 
n = Bulge factor (default = 0) 

Set 
x' = r^n * (x - 0.5) + 0.5 
y' = r^n * (y - 0.5) + 0.5 

(ı kare kökünü kaldırıldı nihai çıkan denklem yapan görebilirsiniz Her neyse gerçek bir sonuç elde etmek için ... bu eşdeğerini yapmak için yerine n'u kullanmalıyız. nce biz tanımlıyorsanız "çıkıntı-faktörü," biz sadece çoğaltmaları ve tek gerçek üs sadece bir avuç ile)

ekstra bölünme bırakabilir, bu muhtemelen en hızlı almak için umut olduğunu.

+1

+1 Buna cevap vermeyeceğim çünkü Android-fu'm sıfır. Ama belki de OP, kodunda bazı temel profilleri denemeli ve hangisinin baskın zaman tüketicileri olduğunu görmelidir. Ya da belki de gereksiz triglerin ortadan kaldırılması yeterlidir. –

+0

@ belisarius Kodumu ve her iki işlevi profillemeyi denedim (yeni x, y konumlarını hesaplama ve bunları değiştirme) her biri için "Picsay Pro" ile karşılaştırıldığında çok zayıf olan yaklaşık 2000 ms sürüyor. – Tony

+1

@Tony * Picsay Pro * muhtemelen bunu OpenGL ... kullanarak ve binlerce gereksiz 'Point' nesnesi oluşturmadan yapıyor. –