Android GPUImage-15: Sobel Edge Detection

该代码示例展示了如何使用GPUImage库在Shader中进行图像处理,包括先应用灰度滤镜,再通过3x3纹理采样进行Sobel边缘检测。Shader计算了图像像素的横向和纵向梯度,以确定边缘并显示结果。

1.效果图

2.shader

 

 public GPUImageSobelEdgeDetectionFilter() {
        super();
        addFilter(new GPUImageGrayscaleFilter());
        addFilter(new GPUImage3x3TextureSamplingFilter(SOBEL_EDGE_DETECTION));
    }

Vertex shader:

 public static final String THREE_X_THREE_TEXTURE_SAMPLING_VERTEX_SHADER = "" +
            "attribute vec4 position;\n" +
            "attribute vec4 inputTextureCoordinate;\n" +
            "\n" +
            "uniform highp float texelWidth; \n" +
            "uniform highp float texelHeight; \n" +
            "\n" +
            "varying vec2 textureCoordinate;\n" +
            "varying vec2 leftTextureCoordinate;\n" +
            "varying vec2 rightTextureCoordinate;\n" +
            "\n" +
            "varying vec2 topTextureCoordinate;\n" +
            "varying vec2 topLeftTextureCoordinate;\n" +
            "varying vec2 topRightTextureCoordinate;\n" +
            "\n" +
            "varying vec2 bottomTextureCoordinate;\n" +
            "varying vec2 bottomLeftTextureCoordinate;\n" +
            "varying vec2 bottomRightTextureCoordinate;\n" +
            "\n" +
            "void main()\n" +
            "{\n" +
            "    gl_Position = position;\n" +
            "\n" +
            "    vec2 widthStep = vec2(texelWidth, 0.0);\n" +
            "    vec2 heightStep = vec2(0.0, texelHeight);\n" +
            "    vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n" +
            "    vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n" +
            "\n" +
            "    textureCoordinate = inputTextureCoordinate.xy;\n" +
            "    leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n" +
            "    rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n" +
            "\n" +
            "    topTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n" +
            "    topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;\n" +
            "    topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;\n" +
            "\n" +
            "    bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;\n" +
            "    bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;\n" +
            "    bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;\n" +
            "}";

Fragment shader:

"precision mediump float;\n" +
            "\n" +
            "varying vec2 textureCoordinate;\n" +
            "varying vec2 leftTextureCoordinate;\n" +
            "varying vec2 rightTextureCoordinate;\n" +
            "\n" +
            "varying vec2 topTextureCoordinate;\n" +
            "varying vec2 topLeftTextureCoordinate;\n" +
            "varying vec2 topRightTextureCoordinate;\n" +
            "\n" +
            "varying vec2 bottomTextureCoordinate;\n" +
            "varying vec2 bottomLeftTextureCoordinate;\n" +
            "varying vec2 bottomRightTextureCoordinate;\n" +
            "\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "\n" +
            "void main()\n" +
            "{\n" +
            "    float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" +
            "    float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" +
            "    float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" +
            "    float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" +
            "    float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" +
            "    float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" +
            "    float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" +
            "    float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" +
            "    float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" +
            "    float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" +
            "\n" +
            "    float mag = length(vec2(h, v));\n" +
            "\n" +
            "    gl_FragColor = vec4(vec3(mag), 1.0);\n" +
            "}";

3.原理

这个filter是继承自GpuImageFilterGroup的,首先进行灰度话,然后进行边缘检测。

首先获取3x3的周围9个点的像素。

"    float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" +
"    float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" +
"\n" +
"    float mag = length(vec2(h, v));\n" +
"\n" +

计算了横向和纵向的梯度,然后显示。

clear, close all %读入图像 H=imread('cell.jpg'): %变为灰度图像 H=rgb2gray(H) %取ROI区域图像 image=H(200:382,200:382): %边缘检测 SegImagel=edge(image,'canny'):SegImage2=edge (image,'sobel'):SegImage3=edge (image,'prewitt'):%sobel边缘检测 [rows,cols] = size(image):sobel_manual = false (rows, cols) ;image_double = double(image):%sobel Gx=[-101:-202:-101]:Gy=[-1-2-1:0 0 0:1 2 1]: 日for i = 2:rows-1 for j = 2:cols-1 region = image_double(i-1:i+1,j-1:j+1): grad_x = sum(sum(region.* Gx)): grad_y = sum(sum(region .* Gy)): gradient_magnitude = sqrt (grad_x 2 + grad_y 2): if gradient_magnitude > 25 sobel_manual(i, j)=true: end end end %prewitt边缘检测 prewitt_manual = false(rows, cols); %prewitt Px=[-101:-101:-101] Py=[-1-1-1:000:1 1 1]: fori=2:rows-1 for j = 2:cols-1 region = image_double(i-1:i+1, j-1:j+1):grad_x = sum(sum(region .* Px)): grady=sum(sum(region.*Py)) gradient_magnitude = sqrt(grad_x^2 + grad_y"2) if gradient_magnitude > 25 prewitt_manual(i,j) = true; end end end %显示图像 subplot (2, 3, 1), imshow(image, []),title('Original Image') subplot (2, 3, 2),imshow(SegImage2),title ("segment Image-sobel")subplot (2,3, 3),imshow(SegImage3),title ("segment Image-prewitt")subplot (2, 3, 4),imshow(SegImagel),title("segment Image") subplot(2,3,5), imshow(sobel_manual), title ("segment Image-sobel (for) ")subplot(2, 3, 6), imshow(prewitt_manual), title ("segment Image-prewitt (for)")sobel和Prewitt不用函数,用for循环,阈值怎么用for循环表示,使结果和函数一样
最新发布
11-04
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值