こんな感じでしょうか。
convert hoge.jpg -fx 'kk=w*0.5;ll=h*0.5;dx=(i-kk);dy=(j-ll);aa=atan2(dy,dx);rr=hypot(dy,dx);rs=rr*rr/hypot(kk,ll);px=kk+rs*cos(aa);py=ll+rs*sin(aa);p{px,py}'
先日の式は、描画点を一旦極座標系に変換し、描画点の距離rrを、「rs=rr*rr/hypot(kk,ll)」で読取点の距離rsに変換し、XY座標に戻す、ということをやっているようです。
さて、魚眼レンズへの変換ですが、原理については下記がわかりやすかったです。
http://odabouta.blog115.fc2.com/blog-entry-10.html
いくつかありますが、等距離射影の「r*θ」がわかりやすいのでこれを採用します。
あと、通常の写真にあたる透視投影がないのですが、これは焦点距離をrとすると「r*tanθ」になるかと思います。
いま、透視投影の写真から点を読取り、等距離投影で描画することを、極座標の距離についてのみ考えます。
読取点rsは透視投影ですので「rs=r1*tanθ」となります。
また、描画点rrは等距離投影ですので「rr=r2*θ」となり「θ=rr/r」となります。
したがって「rs=r1*tan(rr/r2)」が変換式になります。
さて、r1,r2について考えます。
「rs=r1*tanθ」より透視投影の元画像でθ=45°(視野角でいうと倍の90°)の時に「rs=r1」となります。
つまり視野角90°の半径に相当するピクセル数がr1になります。
この視野角90°(π/4)のときの描画半径が「rr=r2*(π/4)」となります。
このあたりは適当に調整してみることになるんじゃないでしょうか。
ちなみに、どうあがいても、元の画像は視野角が180°よりかなり狭いので、魚眼レンズ風にしても、周辺部分はカットするかごまかすことになると思います。
と、ここまで書いてあれですが、たぶんあっていると思う。
質問が分かりずらくて、すみません。
一番知りたいのは、
添付のbeforeからafterの画像を作る場合
imagemagickのconvertの-fxオプションで
どのように記述すれば良いかということです。
▽3
●
quintia ●200ポイント ベストアンサー |
まず小手調べ、というか画像の確認。
画像の中心から短辺で接する円を変換対象にすることにします。
convert -fx "kk=w*0.5;ll=h*0.5;sr=min(kk, ll);dx=i-kk;dy=j-ll;rr=hypot(dx,dy);rr < sr ? p{dx+kk,dy+ll} : 0" in out
変換式はこんな感じ。
convert -fx "kk=w*0.5;ll=h*0.5;sr=min(kk, ll);dx=i-kk;dy=j-ll;rr=hypot(dx,dy);pr=1-2*acos(rr/sr)/pi;px=(rr==0.0 ? 0.0 : pr*dx*sr/rr);py=(rr==0.0 ? 0.0 : pr*dy*sr/rr); rr < sr ? p{px+kk,py+ll} : 0" in out
計算……全部自分でやりました。
http://www.nikon-image.com/enjoy/interview/historynikkor/2000/0010/
正射影の説明はここで読みました
変換の感じをイメージするには、まず半円柱を使った射影を考えた方がいいのかなぁ、と思いました。
画像を半円柱にペッタリとくっつけたときに、変換先の画素から見て《真上》の変換元の画素を求めればよい、と。(左上の図)
これを半球に拡張すると、画像をペッタリと半球にくっつけることはできないので、極座標的な考え方をした方がよさそうです。
さて、画像の座標は左上が0,0です。これだと不便なので、画像の真ん中を0,0にした座標にして考えます。
これが計算中に出てくるdx,dyですね。
でも紙に書いていたときはまだxx,yyって書いてますね。実際の式ではdx,dyです。
あと紙とここの回答にrと書いているのは、実際の式でsrにしてます。
のちのちは頻繁に出てくるので式ではrrに代入してます。
変換先の点(dx,dy)に射影される点をさがすのに、(dx,dy)から見て真上に射影した球面上の点と、半球面の中心、そして中心の直上の点を通る断面を考えます。
いや、z軸と点(dx,dy)を通る断面、と言った方がわかりやすいでしょうか。
点(dx,dy)の直上の球面上の点Sはで表せます。(右上の図)
断面を持ってきます。(右側上から2番目)
になりますから、
です。式中のacosがcosの逆関数です(ていうかtex記法でacosって書くとcos^(-1)の記号になる。なんでww)。
この4分円の弧を、ぐいっ、と引き延ばします。
の直線です。おっと、-fxで扱う角度がラジアンなのでここでもラジアンで書きますよ。
点Sの右側がですので、左側はです。
この線分を変換元画像に持ってきます。
左側を中心に、点(dx,dy)を通る角度での射影を考えます。長さは違うので同じ比で分割したときに点Sにあたる点を探します。(右下の円)
変換元画像の外周上の点は、です。
比率をかけることで変換元の対応する画素を計算しました。
原点(dx=0,dy=0)付近で0割りが発生するので、rr==0.0 かどうかをチェックしています。