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回まわしてるだけですね。^^;
  1. int minusv = (haba - 1) / 2;  
  2.     for(int yy = 0;yy<hh;yy++){  
  3.         for(int xx = 0;xx<ww;xx++){  
  4.             for(int z=0;z<haba;z++){  
  5.                 int idxx = xx + z - minusv;  
  6.                 int idxy = yy;// + z - 2;  
  7.                 if(getPixelIndex(G,idxx,idxy)){  
  8.                     uc[z] = G.GetPixelsDirect3(idxx,idxy);  
  9.                 }  
  10.             }  
  11.             unsigned int ucc = getBock5(uc,haba);  
  12.             GO.SetPixels32(xx,yy,ucc);  
  13.         }  
  14.     }  
  15.     for(int yy = 0;yy<hh;yy++){  
  16.         for(int xx = 0;xx<ww;xx++){  
  17.             for(int z=0;z<haba;z++){  
  18.                 int idxx = xx;// + z - 2;  
  19.                 int idxy = yy + z - minusv;  
  20.                 if(getPixelIndex(GO,idxx,idxy)){  
  21.                     uc[z] = GO.GetPixelsDirect3(idxx,idxy);  
  22.                 }  
  23.             }  
  24.             unsigned int ucc = getBock5(uc,haba);  
  25.             G.SetPixels32(xx,yy,ucc);  
  26.         }  
  27.     }  

0 件のコメント:

コメントを投稿