Android Fourier Transform Realtime - Renderscript

I am trying to apply a 2D Fourier transform on the input frames of a view camera. So here is my renderScript code that runs on each onSurfaceTextureUpdated:

#pragma version(1)
#pragma rs java_package_name(foo.camerarealtimefilters)

rs_allocation inPixels;
int height;
int width;

void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {

    float3 fourierPixel;
    for(int k=0; k<=width; k++){
        for(int l=0; l<=height; l++){
            float3 pixel = convert_float4(rsGetElementAt_uchar4(inPixels, k, l)).rgb;
            float greyOrigPixel = (pixel.r + pixel.g + pixel.b)/3;
            float angle = 2 * M_PI * ( ((x * k) / width) + ((y * l) / height) );
            fourierPixel.rgb = greyOrigPixel*cos(angle);
        };
    };

    out->xyz = convert_uchar3(fourierPixel);
}

InPixels is installed by this method,

public void setInAllocation(Bitmap bmp) {
    inAllocation = Allocation.createFromBitmap(rs, bmp);
    fourierScript.set_inPixels(inAllocation);
};

Now is the math behind my code? In principle, apply the Euler formula, ignore the phase term, because I can not do much with imaginary numbers, and I will draw only the value, that is, the real (cosine) part. I, of course, have a halftone image, as you can see.

Here are my resources:

1) http://homepages.inf.ed.ac.uk/rbf/HIPR2/fourier.htm "... , .."

2) http://www.nayuki.io/page/how-to-implement-the-discrete-fourier-transform .

, , , , , . 2 - 3 .

? , ? , , ( Samsung Galaxy S4 Mini)? DFT .

+4
1

, Java. , , .

  • , float double,

  • , #pragma rs_fp_relaxed,

  • RS, , . , / .

:

rs_allocation angles;
uint32_t      width;
uint32_t      height;
uint32_t      total;

void setupPreCalc(uint32_t w, uint32_t h) {
    uint32_t x;
    uint32_t y;
    float curAngle;

    width = w;
    height = h;
    total = w * h;
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
            curAngle = 2 * M_PI * (y * width + x);
            rsSetElementAt_float(angles, curAngle, x, y);
        }
    }
}
  • ​​ Allocation x y :

void __attribute__((kernel))doFft(uchar4 out, uint32_t x, uint32_t y)

  • , , , , .

  • ​​ , , - , , , . , . RS Allocation, .

pre-calc Allocation , :

void __attribute__((kernel)) doFft(uchar4 out, uint32_t x, uint32_t y) {
    //  Loop over all input allocation points
    uint32_t inX;
    uint32_t inY;
    float    curAngle;
    float4   curPixel;
    float4   curSum = 0.0;

    for (inX = 0; inX < width; inX++) {
        for (inY = 0; inY < height; inY++) {
            curPixel = convert_float4(rsGetElementAt_uchar4(inPixels, x, y));
            curPixel.rgb = (curPixel.r + curPixel.g + curPixel.b) / 3;

            curAngle = rsGetElementAt_float(angles, inX, inY);
            curAngle = curAngle * ((x + (y * width)) / total);

            curSum += curPixel * cos(curAngle);
        }
    }

    out = convert_uchar4(curSum);
}
+2

All Articles