2011-01-26 9 views
10

के साथ गाऊसी फ़िल्टर मैं अपने आईफोन ऐप में कुछ लागू करने के लिए शेडर्स सीखने की कोशिश कर रहा हूं। अब तक मैंने ग्रे उदाहरण, थ्रेसहोल्डिंग इत्यादि के लिए रंगीन छवि बनाने जैसे आसान उदाहरणों को समझ लिया है। उदाहरणों में से अधिकांश उदाहरणों में सरल ऑपरेशन शामिल होते हैं जहां प्रसंस्करण इनपुट छवि पिक्सेल I(x,y) उसी पिक्सेल के रंगों के एक साधारण संशोधन में परिणामओपनजीएल शेडर्स

लेकिन, Convolutions के बारे में कैसे? उदाहरण के लिए, सबसे आसान उदाहरण गॉसियन फ़िल्टर,

जहां आउटपुट छवि पिक्सेल O(x,y) न केवल I(x,y) पर निर्भर करता है बल्कि आसपास के 8 पिक्सल पर भी निर्भर करता है।

O(x,y) = (I(x,y)+ surrounding 8 pixels values)/9; 

आम तौर पर, यह एक एकल छवि बफर के साथ नहीं किया जा सकता है या फिल्टर पिक्सल फ़िल्टर के रूप में बदल जाएगा। मैं इसे शेडर्स के साथ कैसे कर सकता हूं? साथ ही, क्या मुझे सीमाओं को स्वयं संभालना चाहिए? या कोई अंतर्निहित फ़ंक्शन या ऐसा कुछ है जो I(-1,-1) जैसे अमान्य पिक्सेल पहुंच की जांच करता है?

अग्रिम धन्यवाद

पुनश्च: मैं उदार हो जाएगा (पढ़ें: अंक का एक बहुत कुछ देना);)

उत्तर

8

एक नौ मारा गाऊसी कलंक was presented by Daniel Rákos प्रदर्शन करने के लिए एक उच्च अनुकूलित शेडर आधारित दृष्टिकोण । उनकी प्रक्रिया हार्डवेयर में बनावट फ़िल्टरिंग द्वारा प्रदान किए गए अंतर्निहित इंटरपोलेशन का उपयोग करती है ताकि प्रति पास केवल पांच बनावट पढ़ने के लिए नौ-हिट फ़िल्टर किया जा सके। यह आवश्यक बनावट पढ़ने की संख्या को कम करने के लिए अलग क्षैतिज और लंबवत पास में भी विभाजित है।

मैंने ओपनजीएल ईएस और आईओएस जीपीयू के लिए ट्यून किए गए, इसे my image processing framework (GPUImageFastBlurFilter क्लास के तहत) में कार्यान्वित किया। मेरे परीक्षणों में, यह एक आईफोन 4 पर 2.0 एमएस में 640x480 फ्रेम का एकल ब्लर पास कर सकता है, जो कि बहुत तेज़ है।

precision highp float; 

uniform sampler2D inputImageTexture; 

varying mediump vec2 centerTextureCoordinate; 
varying mediump vec2 oneStepLeftTextureCoordinate; 
varying mediump vec2 twoStepsLeftTextureCoordinate; 
varying mediump vec2 oneStepRightTextureCoordinate; 
varying mediump vec2 twoStepsRightTextureCoordinate; 

// const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); 

void main() 
{ 
    lowp vec3 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate).rgb * 0.2270270270; 
    fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate).rgb * 0.3162162162; 
    fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate).rgb * 0.3162162162; 
    fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate).rgb * 0.0702702703; 
    fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate).rgb * 0.0702702703; 

    gl_FragColor = vec4(fragmentColor, 1.0); 
} 

इस प्रदर्शन करने के लिए:

attribute vec4 position; 
attribute vec2 inputTextureCoordinate; 

uniform mediump float texelWidthOffset; 
uniform mediump float texelHeightOffset; 

varying mediump vec2 centerTextureCoordinate; 
varying mediump vec2 oneStepLeftTextureCoordinate; 
varying mediump vec2 twoStepsLeftTextureCoordinate; 
varying mediump vec2 oneStepRightTextureCoordinate; 
varying mediump vec2 twoStepsRightTextureCoordinate; 

void main() 
{ 
    gl_Position = position; 

    vec2 firstOffset = vec2(1.3846153846 * texelWidthOffset, 1.3846153846 * texelHeightOffset); 
    vec2 secondOffset = vec2(3.2307692308 * texelWidthOffset, 3.2307692308 * texelHeightOffset); 

    centerTextureCoordinate = inputTextureCoordinate; 
    oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset; 
    twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset; 
    oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset; 
    twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset; 
} 

और निम्नलिखित टुकड़ा शेडर:

मैं निम्नलिखित शिखर शेडर का इस्तेमाल किया। texelWidthOffset (लंबवत पास के लिए) के लिए 0 मान भेजकर दो पास प्राप्त किए जा सकते हैं, और उसके बाद उस परिणाम को उस दौड़ में खिलाया जा सकता है जहां आप texelHeightOffset (क्षैतिज पास के लिए) के लिए 0 मान देते हैं।

मेरे पास उपरोक्त लिंक ढांचे में संकल्प के कुछ और उन्नत उदाहरण भी हैं, जिनमें सोबेल एज डिटेक्शन शामिल है।

+0

रैखिक इंटरपोलेशन का लाभ का उपयोग करना नया नहीं है। सामान्य आसान तरीका का लाभ कहां है? 10 पिक्सेल रेंज प्राप्त करने के लिए निर्देशांक [-4, -2, 0, 2, 4] पर लुकअप करें और फिर प्रत्येक दो texels के भार को लागू करें? – djmj

+0

@djmj - मुझे यकीन नहीं है कि मैं आपका अनुसरण करता हूं। आपका मतलब क्या आसान तरीका है? आप जिन दो ग्रंथों का जिक्र कर रहे हैं, वे क्या हैं? क्या आपके पास कोई संदर्भ है जिसे आप इंगित कर सकते हैं जो इस दृष्टिकोण का वर्णन करता है? –

+0

देखें: http://drilian.com/journal/images/TextureGrid.png। यदि आप (2, 0.5) पर नमूना करते हैं तो आपको पिक्सेल (1, 0) और (2, 0) के बिलीनेर इंटरपोलेटेड मान मिलेगा। (2, 1) पर नमूनाकरण आपको 4 पड़ोसी पिक्सल का औसत मूल्य मिलेगा!तो बस एक 2 पिक्सेल ऑफ़सेट का उपयोग करें और फिर गाऊशियन भारोत्तोलन लागू करें। – djmj

2

बिलीनेर इंटरपोलेशन के लाभ का उपयोग कर क्षैतिज धुंध। लंबवत धुंध पास एनालॉग है। अनुकूलित करने के लिए अनलोल करें।

//5 offsets for 10 pixel sampling! 
float[5] offset = [-4.0f, -2.0f, 0.0f, 2.0f, 4.0f]; 
//int[5] weight = [1, 4, 6, 4, 1]; //sum = 16 
float[5] weightInverse = [0.0625f, 0.25f, 0.375, 0.25f, 0.0625f]; 

vec4 finalColor = vec4(0.0f); 

for(int i = 0; i < 5; i++) 
    finalColor += texture2D(inputImage, vec2(offset[i], 0.5f)) * weightInverse[i]; 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^