android - 寻找快速图像失真算法

标签 android algorithm image-processing image-manipulation distortion

我正在尝试实现一个使用 shpere 失真过滤器的应用程序。我正在使用 here 中的算法它通过 getPixel() 和 setpixel() 方法更改像素位置。我的问题是它对于 Android 设备来说太慢了,并且有一些应用程序比我的方法更快地实现相同的球体(和其他)过滤器。 (例如 Picsay Pro 应用程序)任何人都可以分享或指导寻找或实现快速失真算法。

实现算法的实际过滤器:

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

替换计算像素位置的代码。

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

最佳答案

I am currently using same algorithm with the one on your link already and it is still too slow for android devices

来 self 的 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 

(请记住,在这个等式中,xy 的范围从 0 到 1。如果您的尺寸范围从 0 到 w,将0.5替换为w/2)

使用 a bit of math , 我们可以看到

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

这使得最终的方程式

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

(我删除了平方根,因为无论如何我们都将结果取为实幂...所以要真正使这个等价,我们应该使用 n/2 而不是 n,但由于我们要定义“膨胀因子”,我们可以忽略额外的除法)

只需少量乘法和一次实数幂运算,这可能是您希望获得的最快速度。

关于android - 寻找快速图像失真算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5542942/

相关文章:

c# - 删除最少数量的国际象棋骑士,这样剩下的骑士就不会威胁到另一个骑士

python - 如何读取多个图像并用它们创建 3D 矩阵?

java - 置换一个字符串

android - Xamarin Android 应用程序图标具有启动器 Activity 的名称

android - 无法选择单选按钮

android - BroadcastReceiver onReceive() 不工作

algorithm - 如何找出时间复杂度是指数的?

opencv - 如何使用 OpenCV 有选择地应用膨胀?

python - 如何在PIL python中获取已旋转角度的文本的x,y坐标?

android - 如何产生默认声音