Android中的球形滤镜

时间:2012-06-07 06:19:26

标签: android image-processing opengl-es geometry raytracing

我必须在android中的图像上应用球形滤镜,我附加了输入和预期的输出图像。输出图像将从输入图像的平方居中区域进行处理,并将其映射到球体。知道如何在Android中执行此操作。我是否必须使用openGL进行此操作,否则单独的2D转换将完成任务。

Input image {
{0}}

4 个答案:

答案 0 :(得分:4)

我刚刚在iOS上使用OpenGL ES 2.0实现了这项工作:

Spherical refraction example

虽然这是在iOS上,我使用的片段着色器可以直接进入Android。使用以下片段着色器完成球形折射部分:

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

center是球体中心的标准化坐标(两个维度中距离为0.0 - 1.0的空格),radius是标准化半径,refractiveIndex是球体的空气/材料指数,aspectRatio是图像的纵横比(用于确保球体在规范化坐标空间中是圆形而不是椭圆形)。

这将计算具有提供的中心和半径的球体的曲面法线,并使用GLSL refract()函数折射传入的矢量并在图像纹理中提供查找坐标。

使用我在this answer中描述的可分离高斯模糊来模糊背景。

此过滤器足够快,可以在iPhone上实时过滤实时视频,因此在大多数Android设备上都应该具有相当的性能。它的源代码可以在我的开源GPUImage框架中的GPUImageSphereRefractionFilter中找到。

答案 1 :(得分:2)

以下代码Fish Eye lens用于创建Sphere并应用一些修改来缩放球体和背景生成,它主要用于方形图像。

答案 2 :(得分:0)

这是一个光线追踪问题。由于OpenGL不提供基于光线的3D,OpenGL很可能甚至不会对您有所帮助。但是,这可能是您正在寻找的。

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

答案 3 :(得分:0)

我同意蒂姆的观点。将一个位图转换为另一个位图不需要3d点,也不需要Ray-trace,完全忘记它,它只需要2d。我不知道opengl是否有内置的东西,但我有足够的3D经验指出你正确的方向。你必须迭代你选择的*圆区域内的所有点*这是线索,并使用FISH-EYE变换找到颜色。网上有很多东西。 希望这有帮助