3

I am working on a application which is related to change the color effect in image. I have done almost everything. Now the problem is that in one of effect i have to give effect like glow egdes filter in photoshop. This filter flow the edges of image with its color and rest of image colors be black. By using BradLarson GPU Image GPUImageSobelEdgeDetectionFilter or GPUImageCannyEdgeDetectionFilter i can find the edges but with white color edges, and i need to find edges in colors. Is their any other way to find edges in color by using GPUImage or openCV. Any help be very helpful for me. Thanks

4

1 回答 1

7

你真的应该为自己编写自定义着色器。它非常平易近人,如果你付出努力,它很快就会变得强大。

也就是说,我认为你正在尝试这样的结果: 在一堆乐高积木上进行边缘检测

您可以通过许多可接受的方式到达这里,但是为 GPUImageTwoInputFilter 的子类编写自定义着色器,然后使用原始图像和 edgeDetection 图像来定位它是我完成您在此处看到的图片的方式。

子类看起来像这样:

#import "OriginalColorEdgeMixer.h"


//Assumes you have targeted this filter with the original image first, then with an edge detection filter that returns white pixels on edges
//We are setting the threshold manually here, but could just as easily be a GLint which is dynamically fed at runtime

#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kOriginalColorEdgeMixer = SHADER_STRING
(
 varying highp vec2 textureCoordinate;
 varying highp vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2;

 lowp float threshold;
 mediump float resultingRed;
 mediump float resultingGreen;
 mediump float resultingBlue;

 void main()
 {
     mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
     threshold = step(0.3, textureColor2.r);

     resultingRed = threshold * textureColor.r;
     resultingGreen = threshold * textureColor.g;
     resultingBlue = threshold *textureColor.b;

     gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
 }
 );
#else
NSString *const kGPUImageDifferenceBlendFragmentShaderString = SHADER_STRING
(
 varying vec2 textureCoordinate;
 varying vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2;

 float threshold;
 float resultingRed;
 float resultingGreen;
 float resultingBlue;

 void main()
 {
     vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
     threshold = step(0.3,textureColor2.r);

     resultingRed = threshold * textureColor.r;
     resultingGreen = threshold * textureColor.g;
     resultingBlue = threshold *textureColor.b;

     gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
 }
 );
#endif

@implementation OriginalColorEdgeMixer

- (id)init;
{
    if (!(self = [super initWithFragmentShaderFromString:kOriginalColorEdgeMixer]))
    {
        return nil;
    }

    return self;
}

@end

正如我写的那样,我们期望 edgeDetection 过滤器的输出是这个自定义过滤器的第二个输入。

我为边缘检测图像上的强度任意选择了 0.3 的阈值,以使原始颜色能够显示出来。这可以通过将其绑定到应用程序中的 UISlider 提供的 GLint 轻松实现动态化(Brad 的示例代码中有许多这样的示例)

为了让刚开始使用 GPUImage 的人清楚起见,使用您编写的自定义过滤器非常容易。我是这样做的:

[self configureCamera];

edgeDetection = [[GPUImageSobelEdgeDetectionFilter alloc] init];
edgeMixer = [[OriginalColorEdgeMixer alloc] init];

[camera addTarget:edgeDetection];
[camera addTarget:edgeMixer];
[edgeDetection addTarget:edgeMixer];
[edgeMixer addTarget:_previewLayer];

[camera startCameraCapture];

总之,不要害怕开始编写一些自定义着色器!学习曲线很简短,调试器抛出的错误非常有助于让您确切地知道您在哪里弄错了语法。

最后,这是记录 OpenGL 特定函数的语法和用法的好地方

于 2013-10-15T21:13:34.157 回答