2012-01-30 4 views
1

現在、画像の一部をぼかそうとしています。私はリンゴのサンプルコードを使用しますhereGLImageProcessing ROI(Region of Interest)

サンプルコード自体は、全体の画像をぼかして、EAGLViewに描画することができます。私がやりたいことは、ROIを供給することによって画像の一部だけをぼかすことです。

私は関数にROIを与える方法を知らない。

画像をビューに描画するコードは次のとおりです。

void drawGL(int wide, int high, float val, int mode) 
{ 
static int prevmode = -1; 
typedef void (*procfunc)(V2fT2f *, float); 

typedef struct { 
    procfunc func; 
    procfunc degen; 
} Filter; 

const Filter filter[] = { 
    { brightness    }, 
    { contrast    }, 
    { extrapolate, greyscale }, 
    { hue     }, 
    { extrapolate, blur  }, // The blur could be exaggerated by downsampling to half size 
}; 
#define NUM_FILTERS (sizeof(filter)/sizeof(filter[0])) 
rt_assert(mode < NUM_FILTERS); 

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrthof(0, wide, 0, high, -1, 1); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glScalef(wide, high, 1); 

glBindTexture(GL_TEXTURE_2D, Input.texID); 

if (prevmode != mode) 
{ 
    prevmode = mode; 
    if (filter[mode].degen) 
    { 
     // Cache degenerate image, potentially a different size than the system framebuffer 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO); 
     glViewport(0, 0, Degen.wide*Degen.s, Degen.high*Degen.t); 
     // The entire framebuffer won't be written to if the image was padded to POT. 
     // In this case, clearing is a performance win on TBDR systems. 
     glClear(GL_COLOR_BUFFER_BIT); 
     glDisable(GL_BLEND); 
     filter[mode].degen(fullquad, 1.0); 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO); 
    } 
} 

// Render filtered image to system framebuffer 
glViewport(0, 0, wide, high); 
filter[mode].func(flipquad, val); 
glCheckError(); 
} 

これは画像をぼかす機能です。私はROIを供給しなければならない、または任意の他の方法は、ROIない画像の部分をぼかすことが可能であるならば、私も知りたい

static void blur(V2fT2f *quad, float t) // t = 1 
{ 
GLint tex; 
V2fT2f tmpquad[4]; 
float offw = t/Input.wide; 
float offh = t/Input.high; 
int i; 

glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); 

// Three pass small blur, using rotated pattern to sample 17 texels: 
// 
// .\/.. 
// ./\\/ 
// \/X/\ rotated samples filter across texel corners 
// /\\/. 
// ../\. 

// Pass one: center nearest sample 
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x); 
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0); 
validateTexEnv(); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Pass two: accumulate two rotated linear samples 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE); 
for (i = 0; i < 4; i++) 
{ 
    tmpquad[i].x = quad[i].s + 1.5 * offw; 
    tmpquad[i].y = quad[i].t + 0.5 * offh; 
    tmpquad[i].s = quad[i].s - 1.5 * offw; 
    tmpquad[i].t = quad[i].t - 0.5 * offh; 
} 
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glActiveTexture(GL_TEXTURE1); 
glEnable(GL_TEXTURE_2D); 
glClientActiveTexture(GL_TEXTURE1); 
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glBindTexture(GL_TEXTURE_2D, tex); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,  GL_INTERPOLATE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,   GL_TEXTURE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,   GL_PREVIOUS); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,   GL_PRIMARY_COLOR); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,  GL_SRC_COLOR); 
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,  GL_PRIMARY_COLOR); 

glColor4f(0.5, 0.5, 0.5, 2.0/5); 
validateTexEnv(); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Pass three: accumulate two rotated linear samples 
for (i = 0; i < 4; i++) 
{ 
    tmpquad[i].x = quad[i].s - 0.5 * offw; 
    tmpquad[i].y = quad[i].t + 1.5 * offh; 
    tmpquad[i].s = quad[i].s + 0.5 * offw; 
    tmpquad[i].t = quad[i].t - 1.5 * offh; 
} 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Restore state 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
glClientActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, Half.texID); 
glDisable(GL_TEXTURE_2D); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,  GL_SRC_ALPHA); 
glActiveTexture(GL_TEXTURE0); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glDisable(GL_BLEND); 
} 

ありがとうございました。

答えて

0

大きなOpenGL ESはありませんが、このコードはサーフェス上に(ROIではなく)全体のテクスチャを使用して動作します。 この例も使用しています。

私は、あなたがしなければならない、と思う:あなたのイメージの

  • カットROIが
  • は、この画像を使用して新しいテクスチャを作成
  • ぼかし、まったく新しい食感、あなたの元のテクスチャの上に
  • セット新しいテクスチャ

また、いくつかのリンク: How to implement a box or gaussian blur on iPhoneBlur Effect (Wet in Wet effect) in Paint Application Using OpenGL-EShow to sharp/blur an uiimage in iphone?

0

まだglScissor()を試しましたか? GLES1.1仕様から

glScissorが矩形を定義は、 座標ウィンドウに、シザーボックスと呼ばれます。最初の2つの引数xとyは、ボックスの左下の の角を指定します。幅と高さを指定して、ボックス の幅と高さを指定します。

シザーテストを有効または無効にするには、引数GL_SCISSOR_TESTを使用してglEnableおよびglDisable を呼び出します。シザーテストは最初は無効になっています。 はさみテストが有効になっている間は、はさみ内にあるピクセルのみ ボックスを描画コマンドで変更できます。ウィンドウ座標はフレームバッファピクセルの共有コーナーに の整数値を持ちます。 glScissor(0,0,1,1)はウィンドウ内の左下のピクセル のみを変更でき、glScissor(0、0、0、0)はウィンドウ内のピクセルを に変更できません。

2回のドローパスが必要な場合があります。最初にフィルタリングされていないイメージ。 2番目はフィルタリングされた画像ですが、シザーテストで描画されます。

+0

glScissor()で円形領域を作成することはできますか? –

+0

いいえ、仕様では明示的に矩形であることが明示されています。サークルが必要な場合は、アルファマスクを使用する必要があります。 – Erik