如果我不必这样做,而且之前必须完成,我宁愿不重新创建轮子。是否有使用OpenGL ES的Sobel过滤器的实现?使用OpenGL ES的C/C++中的索贝尔过滤器
4
A
回答
15
如果Objective-C可以接受,您可以看看我的GPUImage框架及其GPUImageSobelEdgeDetectionFilter。这适用于使用OpenGL ES 2.0片段着色器的Sobel边缘检测。您可以在this answer的“示意图”示例中看到此输出。
如果您不想挖掘Objective-C代码,那么这里的关键工作由两组着色器执行。在第一遍中,我将图像缩小到亮度并将该值存储在红色,绿色和蓝色通道中。我做到这一点使用以下顶点着色器:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
和片段着色器:
precision highp float;
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
之后,我实际执行Sobel边缘检测(用打火机像素在这种情况下是边缘),使用该顶点着色器:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
uniform highp float imageWidthFactor;
uniform highp float imageHeightFactor;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
void main()
{
gl_Position = position;
vec2 widthStep = vec2(imageWidthFactor, 0.0);
vec2 heightStep = vec2(0.0, imageHeightFactor);
vec2 widthHeightStep = vec2(imageWidthFactor, imageHeightFactor);
vec2 widthNegativeHeightStep = vec2(imageWidthFactor, -imageHeightFactor);
textureCoordinate = inputTextureCoordinate.xy;
leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;
rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;
topTextureCoordinate = inputTextureCoordinate.xy + heightStep;
topLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;
topRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;
bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep;
bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;
bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;
}
和该片段着色器:
precision highp float;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float i00 = texture2D(inputImageTexture, textureCoordinate).r;
float im1m1 = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;
float ip1p1 = texture2D(inputImageTexture, topRightTextureCoordinate).r;
float im1p1 = texture2D(inputImageTexture, topLeftTextureCoordinate).r;
float ip1m1 = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;
float im10 = texture2D(inputImageTexture, leftTextureCoordinate).r;
float ip10 = texture2D(inputImageTexture, rightTextureCoordinate).r;
float i0m1 = texture2D(inputImageTexture, bottomTextureCoordinate).r;
float i0p1 = texture2D(inputImageTexture, topTextureCoordinate).r;
float h = -im1p1 - 2.0 * i0p1 - ip1p1 + im1m1 + 2.0 * i0m1 + ip1m1;
float v = -im1m1 - 2.0 * im10 - im1p1 + ip1m1 + 2.0 * ip10 + ip1p1;
float mag = length(vec2(h, v));
gl_FragColor = vec4(vec3(mag), 1.0);
}
imageWidthFactor
和imageHeightFactor
只是输入图像大小的倒数,以像素为单位。
您可能会注意到,这种两遍方法比上面链接的答案更复杂。这是因为当在移动GPU上运行时,原始实现并不是最高效的(至少是iOS设备中的PowerVR品种)。通过去除所有相关的纹理读取并预先计算亮度,以便我只需从最终着色器中的红色通道采样,这种调整后的边缘检测方法在基准测试中的速度比单纯通过所有测试的速度快20倍。
相关问题
- 1. 使用OpenGL ES 2.0的Android上的双线性过滤器
- 2. 在图像上应用索贝尔过滤器
- 3. 如何过滤不索贝尔滤波线在OpenCV中
- 4. sobel过滤器中的不必要的网格线Opengl ES
- 5. 使用CUDA与索贝尔滤波器进行卷积
- 6. OpenGL中的厚贝塞尔曲线
- 7. 从OpenGL ES 1.1过渡到OpenGL ES 2.0
- 8. 使用opengl添加图像过滤器
- 9. SmartEyeGlass中的OpenGL ES
- 10. 如何在使用iPhone SDK的OpenGL ES中使用着色器
- 11. 在BB10中使用OpenGL ES的UI
- 12. 用于iPhone的OpenGL ES 1.1的OpenGL颜色索引?
- 13. Android中的着色器在OpenGL ES中
- 14. 弹性搜索:使用过滤器,应该布尔查询
- 15. 索贝尔算法
- 16. Android中的索贝尔边缘检测
- 17. 在搜索过滤器中使用DN
- 18. 的OpenGL ES glReadPixels
- 19. 使用OpenGL着色器的高斯过滤器
- 20. 机器人的OpenGL ES用α-
- 21. 用于iPad的OpenGL ES分析器
- 22. OpenGL ES 2.0中的着色器Android
- 23. OpenGL着色过滤器
- 24. OpenGL或OpenGL ES
- 25. OpenGL ES 1.1 - 阿尔法面具
- 26. glTexCoordPointer问题使用OpenGL ES
- 27. 正确使用OpenGL ES?
- 28. iPhone的OpenGL-ES:在OpenGL UISwipeGestureRecognizer
- 29. 使用巴贝尔
- 30. 熊猫非索引过滤器的索引过滤器
你见过这个链接:Sobel过滤器示例(http://royger.org/opencl/?p=22)。但是,这在OpenCL中。 – yasouser 2012-03-08 02:37:52