寻找快速的图像失真算法算法、图像、快速

2023-09-10 23:30:45 作者:被判无妻徒刑

我想实现它使用shpere失真过滤器的应用程序。我使用的算法从这里从而改变像素的位置通过与getPixel()和与setPixel()方法。我的问题是,它是Android设备的速度太慢,有它实现相同的球(和其他人)过滤方式比我的方法更快的应用程序。 (例如Picsay Pro的应用程序),任何人都可以共享或给予指导,以寻找或实现快速失真算法。

实际滤波器实现算法:

 公共布尔sphereFilter(位图B,布尔bSmoothi​​ng)
{
    INT nWidth = b.getWidth();
    INT nHeight参数= b.getHeight();

    点[] [] PT =新点[nWidth] [nHeight参数]
    点中旬=新的点();
    mid.x = nWidth / 2;
    mid.y = nHeight参数/ 2;

    双THETA,半径;
    双下一页末,newY;

    为(中间体X = 0 X  - 其中; nWidth ++ x)的
        对于(INT Y = 0; Y< nHeight参数; ++ Y)
        {
            PT [X] [Y] =新的点();
        }

    为(中间体X = 0 X  - 其中; nWidth ++ x)的
        对于(INT Y = 0; Y< nHeight参数; ++ Y)
        {
            INT特鲁克斯= X  -  mid.x;
            INT trueY = Y  -  mid.y;
            THETA = Math.atan2((trueY),(特鲁克斯));

            半径=的Math.sqrt(特鲁克斯*特鲁克斯+ trueY * trueY);

            双newRadius =半径*半径/(Math.max(mid.x,mid.y));

            下一页末= mid.x +(newRadius * Math.cos(THETA));

            如果(下一页末大于0&安培;&安培;下一页末&所述; nWidth)
            {
                PT [X] [Y] .X =(INT)下一页末;
            }
            其他
            {
                PT [X] [Y] .X = 0;
                PT [X] [Y] .Y = 0;
            }

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

            如果(newY大于0&安培;&安培; newY&其中; nHeight参数&安培;&安培;下一页末大于0&安培;&安培;下一页末&所述; nWidth)
            {
                PT [X] [Y] .Y =(INT)newY;
            }
            其他
            {
                PT [X] [Y] .X = PT [X] [Y] .Y = 0;
            }
        }
    offsetFilterAbs(B,PT);
    返回true;
}
 

在code,它取代了计算的像素的立场。

 公共布尔offsetFilterAbs(位图B,点[] []偏移)
{
        INT nWidth = b.getWidth();
        INT nHeight参数= b.getHeight();

        INT xOffset,yOffset;

        对于(INT Y = 0; Y< nHeight参数; ++ Y)
        {
            为(中间体X = 0 X  - 其中; nWidth ++ x)的
            {
                xOffset =偏移[X] [Y] .X;
                yOffset =偏移[X] [Y] .Y;

                如果(yOffset> = 0&安培;&安培; yOffset&其中; nHeight参数&安培;&安培; xOffset> = 0&安培;&安培; xOffset&所述; nWidth)
                {
                    b.setPixel(X,Y,b.getPixel(xOffset,yOffset));
                }
            }
        }

    返回true;
}
 

解决方案   

我目前正在使用相同的算法与一个你的链接已经和它仍然是Android设备太慢

图像算法

这是我的link在上述评论:

鉴于
R = SQRT((X  -  0.5)^ 2 +(Y  -  0.5)^ 2)
A = ArcTan2(Y  -  0.5,X  -  0.5)
N =凸度系数(默认值= 1)

组
X'= R ^ N * COS(一)+0.5
Y'= R ^ N * SIN(A)+ 0.5

(请记住,在这个等式中, X 范围从0到1。如果0您的尺寸跨度为是W ,替换 0.5 W / 2 )的

使用有点数学的,我们可以看到,

余弦(一)= COS(ArcTan2(γ -  0.5中,x  -  0.5))
       =(X  -  0.5)/ R
仙(一)= SIN(ArcTan2(Y  -  0.5,X  -  0.5))
       =(Y  -  0.5)/ R

这使得最后的结果方程

R =(X  -  0.5)^ 2 +(Y  -  0.5)^ 2
N =凸度系数(默认值= 0)

组
X'= R ^ N *(X  -  0.5)+ 0.5
Y'= R ^ N *(Y  -  0.5)+ 0.5

(我删除了平方根,因为我们需要的结果,以一个真正的动力反正...所以真正使这相当于我们应该使用 N / 2 而不是 N ,但因为我们是的定义的胀因素,我们就可以离开了额外的划分)的

由于只有极​​少数乘法和单实幂的,这可能是最快的,你可以希望能得到。

I am trying to implement an application which uses shpere distortion filter. I am using an the algorithm from here which changes pixels location by getPixel() and setpixel() methods. My problem is it is too slow for Android devices and there are applications which implements same sphere(and others) filter way faster than my approach. ( for example Picsay Pro app) Could anyone share or give direction to find or implement fast distortion algorithms.

Actual filter that implements the algorithm:

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

The code that replaces the calculated pixels' positions.

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

From my 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 

(Remember that, in this equation, x and y span from 0 to 1. If your dimensions span from 0 to w, replace 0.5 with w/2)

Using a bit of math, we can see that

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

This makes the final resulting equation

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

(I removed the square-root since we take the result to a real-power anyways... so really to make this equivalent we should use n/2 instead of n, but since we are defining "bulge-factor," we can just leave out the extra division)

With only a handful of multiplications and a single real-exponentiation, this is probably the fastest you can hope to get.