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

标签 iphone ios objective-c opencv gpuimage

我正在开发一个与更改图像颜色效果相关的应用程序。我几乎什么都做了。现在的问题是,在其中一种效果中,我必须在 photoshop 中提供类似发光 egdes 滤镜的效果。该滤镜使图像的边缘流过它的颜色,其余图像颜色为黑色。通过使用 BradLarson GPU Image GPUImageSobelEdgeDetectionFilter 或 GPUImageCannyEdgeDetectionFilter 我可以找到边缘,但边缘是白色的,我需要找到颜色的边缘。他们是否还有其他方法可以使用 GPUImage 或 openCV 查找颜色边缘。 任何帮助对我都非常有帮助。 谢谢

最佳答案

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

就是说,我认为您正在尝试这样的结果: 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 的阈值,以使原始颜色能够显示出来。这可以很容易地通过将它绑定(bind)到从应用程序中的 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

关于iphone - 如何在 iphone 中找到图像的颜色边缘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19151550/

相关文章:

iphone - 如何确保我的 iPhone 应用程序使用 Game Center 沙箱?

ios - 我的计算属性和结构

iphone - 解析 json,不带引号的键

iPhone 应用程序崩溃并且没有留下 .crash 日志文件

ios - 解决配置文件问题后,iPhone 设备中的应用程序安装失败并丢失设备管理

iphone - "release"如何在 ARC 上创建一个 UIWebView

ios - 使用Xcode 11将SPM下载的包保存到项目GIT中

ios - VS 连接 Mac 时,Visual Studio 2017 v15.9 Storyboard 设计器无法连接 Mac

ios - 与 NSTimer 一起使用时,进度条显示滴答动画而不是平滑动画

iphone - 适用于 iOS < 5.0 的 UINavigationBar 上的自定义图像