あけましておめでとうございます。

個人的な事情によりすっかり更新しなくなってしまった画像処理ブログ11回目です。
久々に更新する気になった理由は、なんか年末に急にアクセス数が延びて驚いたからです。
これが噂の水増しだとしても構いません、男は悪女に騙されてるんじゃない!騙されたいんだ!の精神で水増しに騙されると知りつつも書く気にさせてくれればいいのです。


で、今回のネタなんですがさっき風呂入りながら唐突に決めました
まずはこの写真をご覧下さい。

周辺減光サンプル


綺麗な写真ですが僕が撮ったわけでもなくフリー素材です。
この写真を見るとなんか四隅が黒いでしょ?こういうのを周辺減光と言うらしいです。なんかカメラのレンズがほにゃららでどーたらこーたらしてこういう現象らしいですが詳しくは知らん!

とにかく周辺減光の処理をすると、とてもアナログ写真ぽくなり、アナログ厨ざまあwwwな写真がデジタルでも出来るというわけです。


で、実際の画像がこちら。

処理前の画像。
原画像

処理後の画像。
周辺減光処理

画像は最近遊んでるどうぶつの森で三隅に穴を掘り唯一移動できる場所に落とし穴を仕掛けて村の人をハメたところですがどうでもいいですね。


とりあえず処理後の画像を見ると周辺減光出来てます。
ほっとしたのでプログラムの解説いきます。
例によって自作のjavascript画像処理ライブラリOpenCVjsを使いました。
出来たプログラムがこちら。
今回はMakeLightImageメソッドとLightFallメソッドのふたつあります。


//光源画像の生成
//width, height 生成する画像の横と縦の大きさ
//power 光源の強さ (最大255)
//bunbo, bunshi 距離による減衰率の指数となる分子と分母
//radiusX, radiusY 光源自体の縦と横の大きさ

function MakeLightImage(width, height, power, bunbo, bunshi, radiusX, radiusY){
var iplImage = cvCreateImage(width, height);
for(var i = 0 ; i < height ; i++){
  //画像の中心を原点とする処理
  var y = i - height / 2;
  for(var j = 0 ; j < width ; j++){
//画像の中心を原点とする処理
var x = j - width / 2;
//基本の光の強さ
var v = power;
//画像の中心からの距離
var dis2 = (y * y) / (radiusY * radiusY) + (x * x) / (radiusX * radiusX);
//距離が1より大きければ光の強さと距離の関係から明るさを求める(1以下は光の強さがそのまま明るさとなる)
if(dis2 > 1) v /= Math.pow(dis2, bunshi / bunbo) ;
//RGBに代入する
iplImage.RGBA[(j + i * width) * CHANNELS] = v;
iplImage.RGBA[1 + (j + i * width) * CHANNELS] = v;
iplImage.RGBA[2+ (j + i * width) * CHANNELS] = v;
iplImage.RGBA[3 + (j + i * width) * CHANNELS] = 255;
}
  }
  return iplImage;
}



//読み込んだ画像を減光処理する
function LightFall(imgId, iplImage){
//光源の中心の強さ
var power = 255;
//減光率の分子
var bunshi = 80;
//減光率の分母
var bunbo = 100;
//光源の大きさを決める倍率
var bairitsu = 0.4;
//光源の大きさを求める
var lightWidth = iplImage.width * bairitsu;
var lightHeight = iplImage.height * bairitsu;
//光源画像の生成(*1)
var lightImage = MakeLightImage(iplImage.width, iplImage.height, power, bunshi, bunbo, lightWidth, lightHeight);
//画像の複製
var newIplImage = cvCloneImage(iplImage);
//画素同士を掛けて合成(*2)
cvBlendImage(iplImage, lightImage, newIplImage, CV_BLEND_MODE.MUL);
//画像を表示
cvShowImage(imgId, newIplImage);
}


今回中心となるのは(*1)の光源画像の生成をしているMakeLightImageメソッドです。
そもそも何をしているメソッドかというと真っ暗な部分にライトで光を当てたようなIplImage型の画像を生成しています。
実際にMakeLightImageだけで作られた画像をcvShowImageで表示させるとこんな感じです。
周辺減光画像

MakeLightImageの引数なんですが、
第4引数と第5引数の減衰率は物理の定義である光の減衰の法則通りするなら第4引数=1で、第5引数=2となります。
ただ、それでは減水率が強すぎるため適宜調節する必要があります。
第6引数と第7引数は画像の中心からこの大きさまでは光の強さは減衰せず第3引数で指定した値となります。

こうして出来た光源画像とどうぶつの森画像を(*2)cvBlendImageを使い第4引数をCV_BLEND_MODE.MULと指定して画素同士を掛け合わせることで下の減光画像が生成されます。

周辺減光処理

例によってhtml部はありませんがこちらのコードを参考にしてうまいことやってくさい。
久々なんでどんな感じで書いてたのか忘れましたがとりあえずのリハビリブログでした。