2011年4月29日金曜日

画像をぼかす。。とは?

画像をぼかす。。って、ちょこちょこ書いてたわけですが、
技術的には、非常に簡単な考え方です。

下図の黒い部分がドット(ピクセル)だとすると、
その周辺を含めた平均を出し、その値に変換してしまうのです。
要するに、赤いピクセルに着目し(下図の)、
その周辺、たとえば前後左右を1ピクセルずつ考慮すると、
9ピクセルの矩形が考えられます(下図の)。
これの平均を出して、変換後のピクセルの色にしてしまうだけです。
この画像を前後左右1ピクセルを考慮すると、
こうなります。


どうようにして、こんな画像を用意して、
影響範囲を前後左右1ピクセルの3*3=9ドットの平均すると
↓ 
影響範囲を前後左右2ピクセルの5*5=25ドットの平均すると
↓  

影響範囲を前後左右3ピクセルの7*7=49ドットの平均すると
↓  
影響範囲を前後左右4ピクセルの9*9=81ドットの平均すると
↓   


影響範囲を前後左右7ピクセルの15*15=225ドットの平均すると
↓    

影響範囲を前後左右15ピクセルの31*31=961ドットの平均すると
↓   


っとこれでわかるように、演算量は、2乗に比例するような気もするのですが、
実は、タテと横を別々に行っており、最初にヨコでぼかした画像を生成し、
それをさらにタテにぼかして画像を生成します。
よって、計算量は、2乗ではなく、2Nですかね。。

間単に、【平均】なんて書いてしまいましたけど、平均のとりかたに、
重みをつけたりすると、微妙に結果がかわります。

そこらへんは、、、まぁ、いろいろ調べてみましょう^^;^^;
その中のひとつに、【ガウスぼかし】なるものがあります。
まぁたいしたものでもないのですが、たまにはSRCを乗せると。。
二重のLOOPを2回まわしてるだけですね。^^;
int minusv = (haba - 1) / 2;
    for(int yy = 0;yy<hh;yy++){
        for(int xx = 0;xx<ww;xx++){
            for(int z=0;z<haba;z++){
                int idxx = xx + z - minusv;
                int idxy = yy;// + z - 2;
                if(getPixelIndex(G,idxx,idxy)){
                    uc[z] = G.GetPixelsDirect3(idxx,idxy);
                }
            }
            unsigned int ucc = getBock5(uc,haba);
            GO.SetPixels32(xx,yy,ucc);
        }
    }
    for(int yy = 0;yy<hh;yy++){
        for(int xx = 0;xx<ww;xx++){
            for(int z=0;z<haba;z++){
                int idxx = xx;// + z - 2;
                int idxy = yy + z - minusv;
                if(getPixelIndex(GO,idxx,idxy)){
                    uc[z] = GO.GetPixelsDirect3(idxx,idxy);
                }
            }
            unsigned int ucc = getBock5(uc,haba);
            G.SetPixels32(xx,yy,ucc);
        }
    }

0 件のコメント:

コメントを投稿