2009-07-16 52 views
19

我希望能夠拍攝圖像並相對較快地進行模糊處理(比如在0.1秒內)。圖像尺寸幾乎不會大於256 x 256像素。如何在iPhone上實現一個方框或高斯模糊

我是否必須循環每個像素並將它們與鄰居平均,或者是否有更高級別的方法可以執行此操作?

PS:我知道多個框模糊可以接近高斯模糊。

回答

2

您可能想看看Mario Klingemann的StakBlur算法。它不是高斯,但非常接近。

+0

我可以使用CGImageRef作爲StackBlur的輸入嗎?不知道我從哪裏得到像素數據。 – mahboudz 2009-08-11 08:15:39

3

下面是窮人的模糊兩個技巧:

  1. 取圖像,在部分混濁5或6(或包含很多你想要的)一場平局就次,每次offseting的像素夫婦不同方向。在更多方向上繪製更多時間可以讓您更好地模糊,但顯然會折衷處理時間。如果你想要一個半徑相對較小的模糊,這個效果很好。

  2. 對於單色圖像,實際上可以使用陰影中的構建作爲簡單模糊。

+1

如果「部分不透明度」是「耦合像素」的高斯鐘形曲線函數,則可以定義高斯模糊(減去混疊問題)。 – balpha 2009-07-16 21:19:03

+0

你知道多張圖紙對於四向模糊有多快?即,左4和右4。 – willc2 2009-07-17 01:15:07

4

如果你總是或至少經常使用你可能會做在頻域而不是空間域濾波獲得速度相同的模糊設置。

  1. Precaclulate您的濾波圖像G(U,V),這是一種二維高斯
  2. 應用傅里葉變換,以您的輸入圖像f(X,Y) - > F(U,V)
  3. 過濾乘法:H(u,v)= F(u,v)* G(u,v)(按像素乘法,不是矩陣乘法)
  4. 通過逆傅里葉變換將濾波後的圖像轉換回空間域:H (u,v) - > h(x,y)

這種方法的優點是像素乘數與平均鄰域相比,這應該是相當快的。所以如果你處理很多圖像,這可能會有所幫助。

不利的一面是,我不知道你能在iPhone上執行傅里葉變換的速度有多快,所以這可能比其他實現要慢得多。

除此之外,我想因爲iPhone有OpenGL支持,你可以使用它的紋理函數/繪圖來做到這一點。很抱歉地說,雖然我不是OpenGL專家,但實際上並沒有給出任何實際建議。

1

任何通過openGL修改像素級圖像的算法都會慢一點;在OpenGL紋理上逐個像素地操作,然後在每一幀都進行更新,可悲的是性能不足。

花一些時間編寫測試裝置並嘗試執行像素操作,然後再執行復雜的模糊例程。

5

how-do-i-create-blurred-text-in-an-iphone-view:

看看蘋果的GLImageProcessing iPhone樣本。除此之外,它的確有些模糊。

相關的代碼包括:

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

的非常基本的模糊的(或也許更多一軟化的),就是平均2個相鄰像素和的平均值應用到兩個像素。在整個圖像中重複這一點,你會得到輕微的模糊(軟化)。

35

我發現了一個非常快非常糟糕的方式爲iOS3.2 +應用

UIView *myView = [self view]; 
    CALayer *layer = [myView layer]; 
    [layer setRasterizationScale:0.25]; 
    [layer setShouldRasterize:YES]; 

此柵格化視圖到4×4像素塊,然後擴展它備份使用雙線性過濾...這是非常快速和長相好吧,如果你只是想在模態視圖下模糊背景視圖。

要撤消它,只需將柵格化比例設置回1.0或關閉柵格化。