如何在iphone中找到带有颜色的图像边缘?

时间:2013-10-03 05:36:49

标签: iphone ios objective-c opencv gpuimage

我正在开发一个与更改图像颜色效果相关的应用程序。我做了几乎所有事情。现在的问题是,在其中一个效果我必须像photoshop中的发光egdes滤镜一样生效。此滤镜使图像边缘的颜色和其余图像颜色为黑色。通过使用BradLarson GPU Image GPUImageSobelEdgeDetectionFilter或GPUImageCannyEdgeDetectionFilter我可以找到边缘但是有白色边缘,我需要找到颜色边缘。是他们通过使用GPUImage或openCV找到颜色边缘的任何其他方法。 任何帮助对我都很有帮助。  谢谢

1 个答案:

答案 0 :(得分:6)

你真的应该自己去编写自定义着色器。它非常平易近人,如果您投入精力,它可以很快变得强大。

那就是说,我认为你正在尝试这样的结果: Edge Detection on a pile of Lego's

有许多可以接受的方法,但是为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