我正在开发一个与更改图像颜色效果相关的应用程序。我做了几乎所有事情。现在的问题是,在其中一个效果我必须像photoshop中的发光egdes滤镜一样生效。此滤镜使图像边缘的颜色和其余图像颜色为黑色。通过使用BradLarson GPU Image GPUImageSobelEdgeDetectionFilter或GPUImageCannyEdgeDetectionFilter我可以找到边缘但是有白色边缘,我需要找到颜色边缘。是他们通过使用GPUImage或openCV找到颜色边缘的任何其他方法。 任何帮助对我都很有帮助。 谢谢
答案 0 :(得分:6)
你真的应该自己去编写自定义着色器。它非常平易近人,如果您投入精力,它可以很快变得强大。
那就是说,我认为你正在尝试这样的结果:
有许多可以接受的方法,但是为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过滤器的输出成为此自定义过滤器的第二个输入。
我在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];
总之,不要害怕开始编写一些自定义着色器!学习曲线很简短,调试器抛出的错误对于让您准确了解语法的位置非常有帮助。
最后,this is a great place for documentation of the syntax and usage of OpenGL specific functions