Spherical filter in android

2019-01-25 19:28发布

问题:

I have to apply a spherical filter on a image in android, I have attached input and expected output image. Output image will be processed from the squared centered region of input image and mapped it to sphere. Any idea how to do this in Android. Will I have to use openGL for doing this or 2D-trasformation alone will do the task.


回答1:

the following code Fish Eye lens for creating the Sphere and apply some modifications for scaling the sphere and background generation, it will work mostly for square images.



回答2:

I just got an implementation of this working using OpenGL ES 2.0 on iOS:

While this is on iOS, the fragment shader I used can be brought straight across to Android. The spherical refraction portion is accomplished using the following fragment shader:

 varying highp vec2 textureCoordinate;

 uniform sampler2D inputImageTexture;

 uniform highp vec2 center;
 uniform highp float radius;
 uniform highp float aspectRatio;
 uniform highp float refractiveIndex;

 void main()
 {
     highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
     highp float distanceFromCenter = distance(center, textureCoordinateToUse);
     lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);

     distanceFromCenter = distanceFromCenter / radius;

     highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);
     highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));

     highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);

     gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;     
 }

The center is a normalized coordinate for the center of the sphere (from a space of 0.0 - 1.0 in both dimensions), the radius is the normalized radius, the refractiveIndex is the air / material index of your sphere, and the aspectRatio is the aspect ratio of the image (for making sure the sphere is round and not elliptical in the normalized coordinate space).

This calculates the surface normals for a sphere with the supplied center and radius, and uses the GLSL refract() function to refract an incoming vector and provide lookup coordinates in the image texture.

The background is blurred using a separable Gaussian blur that I describe in this answer.

This filter is fast enough to filter live video in real time on an iPhone, so it should be fairly performant on most Android devices. The source code for it can be found within the GPUImageSphereRefractionFilter in my open source GPUImage framework.



回答3:

This is a ray-tracing problem. OpenGL will most likely not even be a help to you here as OpenGL doesnt provide ray based 3D. However, this may be what you are looking for.

http://www1.cs.columbia.edu/CAVE/publications/pdfs/Garg_TR04.pdf



回答4:

I agree with Tim. Transforming one bitmap into another doesn't require 3d points, nor Ray-trace, forget it at all, its simply 2d. I do not know if opengl has something built in, but i have enough 3d experience to point you in the right direction . You have to iterate all points inside the *circle region you choose *this is the clue, and find color using the FISH-EYE transformation. You got plenty on the net. hope this helps