2013-10-03 36 views
3

我正在研究與更改圖像中顏色效果有關的應用程序。我做了幾乎所有事情。現在的問題是,在一個效果之中,我必須在photoshop中使用發光egdes過濾器。此濾鏡以其顏色流動圖像邊緣,其餘圖像顏色爲黑色。通過使用BradLarson GPU圖像GPUImageSobelEdgeDetectionFilter或GPUImageCannyEdgeDetectionFilter我可以找到邊緣,但白色邊緣,我需要找到邊緣的顏色。他們使用GPUImage或openCV以任何其他方式查找顏色邊緣。 任何幫助對我都很有幫助。 謝謝如何在iphone中用它的顏色找到圖像的邊緣?

+0

當然。您可以根據GPUImage中的邊緣檢測創建自定義濾鏡,用您自己的可控顏色替換白色。有幾個人已經完成了這個工作,只需要對着色器代碼進行一些調整即可。 –

+0

@BradLarson:感謝您的回覆,但需要更多幫助。我怎樣才能得到邊緣的原始顏色,如圖像。請解釋一下。這將是非常有幫助的。 – Surjeet

回答

6

你真的應該對自己負責編寫自定義着色器。它非常平易近人,如果你投入了努力,它可以很快變得強大。

這麼說,我想你想的是這樣的結果: Edge Detection on a pile of Lego's

有,你可以得到很多在這裏接受的方式,但編寫自定義着色器GPUImageTwoInputFilter的子類,然後用這兩個目標是原始圖像和邊緣檢測圖像是我如何完成您在此處看到的圖像。

子類會是這個樣子:

#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(布拉德的示例代碼中的很多例子)

爲了清晰起見,人們剛開始使用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

+0

它適用於我,它的工作令人沮喪,我想要的。我試圖創建自定義過濾器,但沒有成功。你解決了我的問題。所以非常感謝Ryan cumley。 – Surjeet

+0

我的榮幸!編程特別容忍重複的嘗試/失敗循環,所以當你的第一次嘗試不成功時不要灰心。調整並再試一次,直到你成功,這是我們如何做到的...... –