Surjeet Singh
Surjeet Singh

Reputation: 11939

How to find edges of image with its colors in iphone?

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

Upvotes: 3

Views: 1541

Answers (1)

ryan cumley
ryan cumley

Reputation: 1931

You really owe it to yourself to play around with writing custom shaders. It's extremely approachable, and can very quickly become powerful if you invest the effort.

That said, I think you're trying for something like this result: Edge Detection on a pile of Lego's

There are many acceptable ways you could get here, but writing a custom shader for a subclass of GPUImageTwoInputFilter then targeting it with both the original image AND the edgeDetection image is how I accomplished the picture you see here.

The subclass would look something like this:

#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

As I've written this, we're expecting the edgeDetection filter's output to be the second input of this custom filter.

I arbitrarily chose a threshold value of 0.3 for intensities on the edgeDetection image to enable the original color to show through. This could easily be made dynamic by tying it to a GLint fed from a UISlider in your app (many examples of this in Brad's sample code)

For the sake of clarity for people just starting out with GPUImage, using that custom filter you wrote is really easy. I did it like this:

[self configureCamera];

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

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

[camera startCameraCapture];

In summary, don't be scared to start writing some custom shaders! The learning curve is brief, and the errors thrown by the debugger are extremely helpful in letting you know exactly where you f**d up the syntax.

Lastly, this is a great place for documentation of the syntax and usage of OpenGL specific functions

Upvotes: 7

Related Questions