正距円筒画像の変形について
はじめまして。藤と申します。
当方、大学で画像処理の研究をしています。
今、研究でパノラマ画像を扱っており、正距円筒画像を6面キューブ画像に展開したいと考えています。
こちらで公開されているpano2cube.exeのソースを参考にC++で展開のプログラムを書いているのですが、
計算結果を反転コピーするところの処理が上手く再現できません。
もしよろしければソースについてご教授いただけないでしょうか?
  • 2012/12/22 (Sat) 00:57:15
Re: 正距円筒画像の変形について
C, C++ は不案内なのですが。

少数部分は小数点以下4桁固定で、計算は整数型と同じ速度が得られる Currency 型を
利用しています。VB, C# には用意されているようですが、C, C++ ではどうでしょう。

4桁に丸める処理を追加されると良いかもしれません。

横幅が 8192 ピクセルの場合は R2 は 2048 ですね。
計算結果が 123.4567 のとき、反転結果は 1923.5433 になる(たぶん)ような処理を
しています。
  • ほんだ
  • 2012/12/23 (Sun) 01:15:15
Re: 正距円筒画像の変形について
ほんださん

お世話になっております。
ご指摘ありがとうございます。
質問ばかりで申し訳ないのですが、例えば上面の三角形を求める式でUが(ArcTan(U / V) * 180 / Pi) * R / 45、
Vが(ArcTan(Sqrt(U * U + V * V) / R) * 180 / Pi) * R / 45とあるのですが、
領域反転せずに、直接隣の領域の三角形を求めるとすればこの式をどのように書き換えればいいのでしょうか?
実は、今回配列を使用せずに直接それぞれのピクセルのBGRを参照して、結果画像に画素を移動しているので上手く教えていただいたような処理をすることが出来ないのです。
当方、まだ知識が少なく色々と質問をしてしまいお忙しいところ煩わしいかと思いますが、教えていただければ幸いです。
よろしくお願いします。
  • 2012/12/24 (Mon) 00:31:01
Re: 正距円筒画像の変形について
>領域反転せずに、直接隣の領域の三角形を求めるとすればこの式をどのように書き換えればいいのでしょうか?

ん~。それを考えるのが面倒だったので、反転方式としたんですやん。
サンプルコードの上の方にある「変換の考え方」「実際の計算」のトピックを
一度お読みになられてはいかがでしょう?

あとは、redmesh_cube_array.jpg をプリントアウトして切り抜いてキューブにしてみると
見えて来るかもしれません。

楽しんでくださいね。
  • ほんだ
  • 2012/12/24 (Mon) 11:26:44
Re: 正距円筒画像の変形について
ほんださん

これから試行錯誤したいと思います。
またよろしくおねがいします。
  • 2012/12/24 (Mon) 12:40:31
Re: 正距円筒画像の変形について
ほんださん

お世話になっております。
お陰様で、redmesh_cube_array.jpgを使用して反転処理を実現することができました。
そこで一つ質問なのですが、mesh画像のような1と2の領域が同じ画像以外の画像でこの処理を行うと
1の領域の画素が、そのまま2の領域にコピーされてしまうのではないのでしょうか?
  • 2012/12/25 (Tue) 15:03:31
Re: 正距円筒画像の変形について
藤さん
変形した画像に分割線をいれて、t1..t16, s1..s16 の番号を付けた画像を示します。
  • ほんだ
  • 2012/12/26 (Wed) 23:09:35
Re: 正距円筒画像の変形について
藤さん
次に、上の画像をキューブに組み立てた画像を示します。
サンプルコードの計算式は、図の原点と基準点を結ぶ直線と赤線の領域にあるキューブ上の
総ての点との角度を求めるためのものです。つまり、赤線の領域に対してのみ有効です。

配列を使わない場合は他の領域すべてに対して有効な角度を求める計算式を考え出さなければ
なりません。

頑張ってね。
  • ほんだ
  • 2012/12/26 (Wed) 23:11:05
Re: 正距円筒画像の変形について
ほんださん

詳しい説明ありがとうございます。
また一つ質問になってしまうのですが、例えばt1,s1の領域とt3,s3の領域は画像上で見ると同じに見えるのですが、計算式は同じにはならないのでしょうか?
  • 2012/12/27 (Thu) 15:30:04
Re: 正距円筒画像の変形について
ほんださん

t1,s1の領域からt3,s3, t5,s5, t7,s7の領域を作ることができました。
式の中のUを変えて原点の位置をずらすことで実現しました。
ほんださんのおかげです。ありがとうございます。
現時点での画像を添付いたします。
s2,t2以降については作成中なのですが、こちらは中々上手くいかないです。
なんとか今年中に完成したいと思いますが難しそうです。
  • 2012/12/27 (Thu) 19:24:38
Re: 正距円筒画像の変形について
藤さん

>t1,s1の領域からt3,s3, t5,s5, t7,s7の領域を作ることができました。

おぉ素晴らしいですね。あとは、t2, t9, t10, s2, s10 だけですね。

ご案内になるかもしれませんが、座標を求める式において、
180 / Pi
は ArcTan が返すラジアン値を度数に変換しています。
また、
R / 45
は、求めた角度を「変換の考え方」のトピックの (3), (4) の式に代入した結果
得られたものです。

「実際の計算」のトピックにある図を t2, t9, t10, s2, s10 の領域について
紙と鉛筆で試行錯誤して見て下さい。
私の手元には、あの式に行き着くまでの30ページ程度のノートがあります。

頑張ってね。
  • ほんだ
  • 2012/12/27 (Thu) 21:14:04
Re: 正距円筒画像の変形について
ほんださん

明けましておめでとうございます。藤です。
昨年ほんださんから教えていただいた事を参考に年末に試行錯誤を繰り返してみました。
そこでt2,s2の式について考えていたのですが、前回t1,s1の領域からt3,s3を作ったとき、
例えば四角形の式において、以下のようにループでずらした分だけ式の中でxから引くことで原点を移動させました。
for(y = R; y < 3*R-1; y++)
for(x = 2*R; x < 3*R-1; x++)
sU = (atan2( (double)(x-2*R), (double)R)*180/Pi)*R/45;
sV = (atan2( (double)sqrt((double)(x-2*R)*(x-2*R) + R*R), (double)R*2-y)*180/Pi)*R/45;
s1とs2の領域について図形としては合同だと思ったので、s2を作るとしたら、x軸について反転させるものと思いxを-xに変えてみたのですが思うような結果が得られませんでした。
式変形だけではs2の領域を作ることは出来ないのでしょうか?



  • 2013/01/04 (Fri) 10:37:07
Re: 正距円筒画像の変形について
藤さん

実際にコードを書いて試してはいませんが、
t2, s2 領域では、Xについては t1, s1 領域で求められる角度を90度から引けば
良いだけのような気がします。Yはそのままで行けますよね。

t4, s4 領域では180度から引いてYはそのまま。

s9..s16, t9..t16 領域のYは上で求められる角度を180度から引けば良いように
思います。

試してみて下さい。
  • ほんだ
  • 2013/01/04 (Fri) 20:22:58
Re: 正距円筒画像の変形について
横幅が 8192 ピクセルの場合
t2, s2 では R2 は 2048 なので、t1, s1 で求めた結果を 2048 - 1 から引くだけで良いと思います。
t4, s4 では R2 が 4096 なので以下同じです。

というわけで、最初のコメントに戻ってしまいました。
  • ほんだ
  • 2013/01/05 (Sat) 00:52:34
Re: 正距円筒画像の変形について
// 上面の三角形(1)
for V := 0 to R - 1 do
for U := 0 to V do
begin
// iU, dU
if V = 0 then
begin
// 三角形の頂点
mx[U, V].iU := 0;
mx[U, V].dU := 0;
// t2 の三角形の頂点
mx[R * 2 - 1, V].iU := 0;
mx[R * 2 - 1, V].dU := 0;
end
else
begin
E := (ArcTan(U / V) * 180 / Pi) * R / 45;
mx[U, V].iU := Trunc(E);
mx[U, V].dU := E - Trunc(E);
// t2
mx[R * 2 - 1 - U, V].iU := Trunc(R * 2 - 1 - E);
mx[R * 2 - 1 - U, V].dU := R * 2 - 1 - E - Trunc(R * 2 - 1 - E);
end;
// iV, dV
E := (ArcTan(Sqrt(U * U + V * V) / R) * 180 / Pi) * R / 45;
mx[U, V].iV := Trunc(E);
mx[U, V].dV := E - Trunc(E);
// t2
mx[R * 2 - 1 - U, V].iU := Trunc(R * 2 - 1 - E);
mx[R * 2 - 1 - U, V].dU := R * 2 - 1 - E - Trunc(R * 2 - 1 - E);
end;

こんな感じで行けるような気がします。
  • ほんだ
  • 2013/01/05 (Sat) 01:31:36
Re: 正距円筒画像の変形について
領域 t2 上の任意の点 Pについて

求める θU は、直線 AB と AP の角度、θV は、直線 OA と OP の角度です。

θU は、90度から θU2 を引いた角度に等しいので、

Tan(θU2) = X2 / Y = (R * 2 - X) / Y
θU2 = ArcTan((R * 2 - X) / Y)
θU = 90 - ArcTan((R * 2 - X) / Y)

角度からピクセル値を求める式
U = W * θU / 360

にθU を代入すると
U = W * (90 - ArcTan((R * 2 - X) / Y)) / 360

となります。V は t1 と同じですね。
  • ほんだ
  • 2013/01/05 (Sat) 03:21:06
Re: 正距円筒画像の変形について
藤さん

どう書けば動くかを求めるのではなく、
どうしてそう書けば動くのかを知ろうとして下さい。
  • ほんだ
  • 2013/01/05 (Sat) 03:28:43
Re: 正距円筒画像の変形について
U = W * (90 - ArcTan((R * 2 - X) / Y)) / 360
において、

W = 8R なので、
U = 8R * (90 - ArcTan((R * 2 - X) / Y)) / 360
U = R * (90 - ArcTan((R * 2 - X) / Y)) / 45

ArcTan の返値はラジアンなので度数に変換すると
U = R * (90 - (ArcTan((R * 2 - X) / Y)) * 180 / Pi) / 45
が領域 t2 の計算式になると思います。
  • ほんだ
  • 2013/01/05 (Sat) 11:43:53
Re: 正距円筒画像の変形について
領域 s2 上の任意の点 Pについて

求める θU は、直線 AB と AP の角度、θV は、直線 OA と OP の角度です。

θU は、90度から θU2 を引いた角度に等しいので、

Tan(θU2) = X2 / R = (R * 2 - X) / R
θU2 = ArcTan((R * 2 - X) / R)
θU = 90 - ArcTan((R * 2 - X) / R)

角度からピクセル値を求める式
U = W * θU / 360

にθU を代入すると
U = W * (90 - ArcTan((R * 2 - X) / R)) / 360

W = 8R なので、
U = 8R * (90 - ArcTan((R * 2 - X) / R)) / 360
U = R * (90 - ArcTan((R * 2 - X) / R)) / 45

ArcTan の返値はラジアンなので度数に変換すると
U = R * (90 - (ArcTan((R * 2 - X) / R)) * 180 / Pi) / 45
が領域 s2 の計算式になると思います。

V は s1 と同じですね。

  • ほんだ
  • 2013/01/05 (Sat) 12:15:01
Re: 正距円筒画像の変形について
さて、ここで問題です。

領域 t2, s2 で角度を求めるための図を参考にして
領域 s9, t9, s10, t10 で角度を求めるための図を描いて下さい。

紙と鉛筆で書いたモノでよいので、それを写してアップロードして下さい。
  • ほんだ
  • 2013/01/05 (Sat) 14:30:18
Re: 正距円筒画像の変形について
ほんださん

多くのご助言ありがとうございました。
卒論の締切に焦るばかり、ほんださんのおっしゃるようにどう書けば動くのかを求めすぎていたように思います。
これから教えていただいたことを参考にどうしてそう書けば動くのかについて学んでいきたいと思います。
本当にありがとうございました。
  • 2013/01/05 (Sat) 16:59:00

返信フォーム






プレビュー (投稿前に内容を確認)