はじめに
MATLAB,Python,Scilab,Julia比較するシリーズの第3章。
第2章では回帰関連の話がメインだった。
第3章は画像処理関連の話がメインとなる。
基本的には以下の流れとなる。
- 画像の読み込み、保存
- グレースケール
- 畳み込み系
- アフィン変換
- 射影変換
ちなみに、問答方式じゃない方も記事もある。
問答方式に合わせて内容を強化していく予定。
書籍とか
その他の章
概要偏
- 第3章スタート。
- 畳み込み、アフィン変換、射影変換をやる予定。
- 地味に畳み込みニューラルネットワークの基礎知識になり得るかも。
- 恒例のMATLAB、Python、Scilab、Juliaで動作させてみる予定。
- 内容によっては苦手なもの、できないものが発生するかも。
画像操作
- 画像の読み込み、保存について具体的にやることを列挙。
- カメラキャプチャもやるが、ツール、言語によってはできないor難しい場合あり。
- 使用する画像は例の「犬と自転車」。
- お試し画像処理は赤成分の抽出と左右反転をやってみる。
MATLAB
- MATLABで画像処理。
- 読み込みはimread。
- 画像の構成を維持した2次元配列に、RGBの3チャンネルがぶら下がる。
- 結果として3次元配列になる。
- 画像の構成を維持した2次元配列に、RGBの3チャンネルがぶら下がる。
- 画像の加工は配列操作を駆使する。
- 配列操作の基本を身に着けた方がお得。
Python
- Pythonで画像処理。
- OpenCVを利用するcv2パッケージが必要。
- 1ピクセルのRBGの並びがBGRになっている点に注意。
- 反転させる場合のスライシングは::-1。
- Pythonでカメラキャプチャ実施。
- cv2で実施可能。
- 1フレームずつ取得でき、1フレーム単位でみれば画像と一緒。
- 実際には処理負荷軽減、分散等を意識することが多い。
Scilab
- Scilabで画像処理。
- IPCVパッケージのインストールが必要。
- 中身はOpenCV。
- IPCVパッケージのインストールが必要。
- OpenCVベースなので色の並びがBGRかと思いきやRGB。
- 終端要素しては$。
- ScilabのIPCVでカメラキャプチャ。
- Scilab、IPCVというよりOpenCVの機能。
- 基本的にはPythonで実施したことと同じことは可能。
- API名が異なる点に注意。
Julia
- Juliaで画像処理。
- ImagesとImageViewのパッケージをインストール。
- OpenCVではなくImageMagickを使用したパッケージなので他の環境と性格が異なる。
- ImagesのAPIとやり取りする場合は基本構造体ベースだが、処理をする際は配列にするなど行ったり来たりが発生する。
グレースケール
- 画像処理の実験をする際はグレースケールにしておくのが一般的。
- カラー(RGB)の際は各チャンネルに対して同じ処理をすれば良い。
- グレースケールにも種類がある。
- SDTV規格が一般的らしい。
- 犬と自転車の画像を元にRGB平均とSDTV規格を比較してみた。
- ぶっちゃけ思ったほどの差は感じない。
- とりあえずSDTVで進める。
- 今後の予定としては各ツール、各言語でこれらを実施し、クセのようなものを認識する。
MATLAB
- MATLABでRGB平均とSDTVのグレースケール化実施。
- 画像データの型の都合でuint8のキャストが必要。
- unit8キャスト時に小数点以下が自動で四捨五入される。
- 小数点以下切り捨て(0方向への丸め)をしたい場合はfix関数を使用する。
Python
- Python(NumPy)でRGB平均とSDTVのグレースケール化実施。
- 次いでにOpenCVによるグレースケール化も。
- OpenCVによるグレースケール化はコーデック依存な面がある。
- 画像データはの1チャンネル1ピクセルは8bit長。
Scilab
- ScilabでRGB平均とSDTVのグレースケール化実施。
- 基本的にはMATLABと似た感じにはなる。
- デフォルトで0方向へ丸め。
- 整数型でキャストすると内部の変数も演算前に整数型に変わってしまう。
- これを抑制するためにdoubleへキャストなどを使用する。
Julia
- JuliaでRGB平均とSDTVのグレースケール化実施。
- 基本的な流れは他の環境と一緒。
- データ構造の違いに気を付ける必要がある。
- さらに各チャンネル情報も0~1の正規化されたものになってる点にも注意。
ガウシアンフィルタ
- 画像の読み込み、赤成分抽出、反転、書き込み、グレースケール化の下準備は終わった。
- これからガウシアンフィルタをやろうとしているところ。
- 畳み込み、2次ガウス分布等の事前知識を説明してから実際に処理を実施している予定。
- 畳み込み演算について説明。
- 一応、図解。
- やっていることは内積。
- 演算していることは分かるが、どのような効能が得られるかは分かりにくい。
- 畳み込み積分について超簡単に説明。
- 畳み込み積分の演算結果についてアニメーション。
- ノイズ除去の様子がわかる。
- 2次ガウス分布関数について確認。
- 前回の畳み込み積分で使用した関数は1次ガウス分布関数。
- 数式で確認。
- 実施にグラフ表示で確認。
- 中心に重みが寄ってる山なりの関数。
- 元信号が増幅、減衰しないように、総和が1.0になるように細工するのが一般的。
- 「良く使われるガウス分布カーネル」を確認。
- 前回の2次ガウス分布と大体似たような値。
- だたし、数値の表現としてはシンプル。
- この後は実際にガウシアンフィルタを試してみる。
- 画像は恒例の「犬と自転車」
- 畳み込み演算は今後使いまくる予定なので関数かしておく方針。
MATLAB
- MATLABでガウシアンフィルタを実施。
- 畳み込み演算は関数化。
- MATLABのsumは行と列のそれぞれの総和しか計算できない。(version依存)
- RGB 3chに対して同じ処理を実施している。
Python
- Python(NumPy)でガウシアンフィルタを実施。
- 畳み込み演算は関数化。
- NumPyのsumは行列の総和。
- 行、列の総和の場合はaxisオプションを使用。
- RGB 3chに対して同じ処理を実施。
Scilab
- Scilabでガウシアンフィルタを実施。
- 畳み込み演算は関数化。
- Scialbのsumは行列の総和。
- 行、列の総和の場合は第2引数を使用。
- RGB 3chに対して同じ処理を実施。
Julia
- Juliaでガウシアンフィルタを実施。
- 畳み込み演算は関数化。
- Juliaのsumは行列の総和。
- 行、列の総和の場合はdimsオプションを使用。
- RGB 3chに対して同じ処理を実施。
- データ構造が大きく異なるので注意。
微分フィルタ
- 画像処理と言えば、エッジ検出が割と有名。
- エッジをデータでみるとどういうことなのを確認するために輝度のグラフを出してみた。
- 山と谷が検知できればエッジ検知になりそう。
- 普通に考えると、ピクセル単位で評価するif文の嵐になりそうだが・・・。
- エッジ検出をするには、変化の大きさを強調できる微分が相性が良い。
- だからといって導関数を求める必要はない。
- tanh関数で畳み込み積分をすると微分相当の結果が得られる。
- あくまで微分相当であり、微分の結果そのものではない。
- 欲しいのは変化の強調であるため、問題無い。
- tanh関数による畳み込み積分は、単なる引き算として解釈できる。
- 微分の結果を強めるには、ある程度距離がある方が良い。
- 微分するとノイズが乗りやすいので除去する策も必要。
- 元画像の特性が消えないようガウシアンにした方が良い。
- 各種畳み込みカーネル。
- 微分特性を付けてエッジ検出したい。
- 微分の特性をより強くしたい。
- 移動平均でノイズをちょっと除去したい。
- 元画像の特徴を残すために単純移動平均じゃなくてガウシアンにしたい。
- 各種フィルタについて説明。
- 微分フィルタ
- 一次微分フィルタ
- Prewittフィルタ
- Sobelフィルタ
- 単純にSobelフィルタのカーネルで畳み込みをしても期待する結果にならない。
- マイナス値がでるので、絶対値なり二乗なりで対処する必要あり。
- 横方向、縦方向のエッジしか検知できないので、合成する。
- Sobelフィルタの実験手順。
- とりあえずガウシアンフィルタもかけておく。
- 縦横の2種類のSobelフィルタと、その結果の合成も忘れずに。
MATLAB
- MATLABでSobelフィルタを実施。
- 想定通りの結果が得られた。
- というより、前回までの結果が実はMATLABで実施したものだった。
- 他の環境、言語でも同様の結果が得られるかが確認ポイントになる。
Python
- Python(NumPy)でSobelフィルタを実施。
- MATLABと同じ結果が得られた。
- np.arrayがuint8になっている状態を維持する必要がある。
- imwrite時にuint8になっていないと期待した出力にならない。
Scilab
- ScilabでSobelフィルタを実施。
- MATLABと同じ結果が得られた。
- uint8にキャストする際は、事前にmin,maxを使用してサチュレーションをしておく必要がある。
Julia
- JuliaでSobelフィルタを実施。
- MATLABと同じ結果が得られた。
- コード上の演算はほぼMATLABと一緒
- 画像が0~1で正規化されている点に注意。
画像書き出し時にも再度正規化しておくと良い。
Python
- Python(NumPy)でSobelフィルタを実施。
- MATLABと同じ結果が得られた。
- np.arrayがuint8になっている状態を維持する必要がある。
- imwrite時にuint8になっていないと期待した出力にならない。
非極大値抑制(Non-Maximum Suppression)
- エッジ検出もっとシビアに行いたい。
- 非極大値抑制を使うといい感じになる。
- 同様の用語が物体検出器でも出てくるが別物。
- 具体的な話は順を追って説明する。
- 非極大値抑制の大雑把な雰囲気を確認。
- 図で確認。
- 2次元平面に実施する場合の考え方を確認。
- これも図で確認。
- 様々な方向から見た極大値を意識する必要がある。
- 非極大値抑制の「勾配の特定方法」について解説。
- 2次元平面で考えるためには勾配の方向が重要。
- 勾配の方向は、横、縦それぞれの傾斜度合いから推定可能。
- 実際にはarctan関数を使用する。
- arctan関数はtan関数の逆関数。
- 実際にはarctan関数を使用する。
- 非極大値抑制を実現するための斜面の方向パターンについて説明。
- arctan関数で細かい方向は特定できるが、基本は4パターンに丸められる。
- 判定ピクセルマスを5×5、7×7などにしてもっと細かくするパターンもある。
- 非極大値抑制をプログラムで実現する手順を確認。
- 一個一個はそれほど複雑ではない。(はず)
- 勾配方向角度については、度数法で扱う。
- プログラム的には弧度法の方が扱いやすいが、人間から見た分かり易さを重視。
MATLAB
- MATLABで非極大値抑制を実施。
- 想定通りの結果が得られた。
- 論理インデックスサーチを利用している個所がある。
- インデックスサーチについては別途説明。
Python
- Python(NumPy)で非極大値抑制を実施。
- MATLABと同一の結果が得られた。
- MATLABでは論理インデックスサーチを使用したが、ここではあえて線形インデックスサーチを使用。
Scilab
- Scilabで非極大値抑制を実施。
- MATLABと同様の結果が得られた。
- コードもほぼ一緒。
- Scilabも線形&論理インデックスサーチが存在する。
Julia
- Juliaで非極大値抑制を実施。
- MATLABと同様の結果が得られた。
- ピクセルの正規化の話と、”.”によるブロードキャストは毎度な話。
インデックスサーチ
- MATLABで線形インデックスサーチを実施。
- 基本的な考え方は配列の添え字指定のベクトル化。
- 様々な指定方法で行列内部データの参照、書き込みが可能となる。
- MATLABで論理インデックスサーチの挙動を確認。
- 評価式の結果が論理インデックスとなり、それを行列に渡すことで1、またはtrueの部分の要素の参照及び書き換えが可能。
- find関数を使用すると評価式に該当する線形インデックスが取得できる。
- これらはMATLAB以外の環境、言語でも使用できることが多い。
- 各ツール、各言語で線形インデックスサーチを確認。
- 基本的にはどの環境でも実施可能。
- MATLABのfind相当の関数がwhereだったりfindallだったりする程度の差はある。
- 各ツール、各言語で論理インデックスサーチを実施。
- 基本的には似たり寄ったりの記述方法。
- 各ツール、各言語における論理インデックスサーチと線形インデックスサートの一覧表を作成。
- SQLやコンテナライブラリにも似たような機能が実装されていることが多いので、仕様を確認しておくと楽ができる。
Hysteresis Threshold
- 非極大値抑制を掛けた後の画像はなんか暗い。
- よって2値化して、線をはっきりくっきりせされば良い。
- 閾値で2値化するのが一番シンプルだが、必要な線が消えたり、不要な線が残ったりしやすい
- これに対して、Hysteresis Thresholdを使うと言い感じになる。
- Hysteresis Thresholdの雰囲気をセンサ情報のヒス付き判定と関連させて説明。
- Hysteresis Thresholdを図解で説明。
- Hysteresis Thresholdの具体的な判定方法を説明。
- Hysteresis Thresholdを実施するための手順を確認。
- 非極大値抑制にHysteresis Thresholdを加えただけ。
- 上記の手順はCanny法という名称がついている。
- Wikipediaに記載されているCanny法について確認。
MATLAB
- 非極大値抑制にHysteresis Thresholdを加えた、Canny法による2値化をMATLABで実施。
- 基本的にはいままでのコードを再利用。
- 追加分はHysteresis Thresholdの部分。
Python
- 非極大値抑制にHysteresis Thresholdを加えた、Canny法による2値化をPython(NumPy)で実施。
- 基本的にはいままでのコードを再利用。
- 追加分はHysteresis Thresholdの部分。
Scilab
- 非極大値抑制にHysteresis Thresholdを加えた、Canny法による2値化をScilabで実施。
- 基本的にはいままでのコードを再利用。
- 環境によってはメモリ不足に陥るのでJavaヒープメモリを調整する必要がある。
Julia
- 非極大値抑制にHysteresis Thresholdを加えた、Canny法による2値化をJuliaで実施。
- 環境依存はあるかもしれないが、処理としてはMATLABよりも高速。
- JITコンパイル後はネイティブコードで動作するため。
アフィン変換
- 画像処理は、特徴を抽出する畳み込みとは別に座標を変換するものもある。
- 座標変換の代表的な手法としてアフィン変換がある。
- アフィン変換は現座標を元に直線的に変換先を決定する手法。
- アフィン変換でなにができるのかを確認。
- 伸縮、移動、回転、剪断が可能。
- アニメーションgifでアフィン変換のイメージを見てみた。
- 数式的な解釈の確認。
- アフィン変換の数式の変形して同次座標系へ。
- この表現の方が、他の座標変換の時に生きる。
- このままやるといろいろ問題が起きる。
- 空間不足。
- 変換先が満遍なくならない。
- アフィン変換を実施する上での問題を確認。
- 空間不足問題とまだら模様問題。
- 空間不足問題に対しては、キャンパス拡張にて対策。
- まだら模様問題は、別途原因と対策を説明予定。
キャンバス拡張
MATLAB
- キャンパス拡張をMATLABで実施。
- 元画像のサイズを元に指定ピクセル分大き目の黒空間を作成。
- その黒空間の真ん中に元画像をコピー。
Python
- キャンパス拡張をPython(NumPy)で実施。
- 手順としてはMATLABと一緒。
- 黒空間を作る際にuint8の型で作成。
- 保存時にキャストしてもOK。
Scilab
- キャンパス拡張をScilabで実施。
- 手順としてはMATLABと一緒。
- メモリ不足になることがあるため、画像を小さめにしておいた方が良い。
Julia
- キャンパス拡張をJuliaで実施。
- 手順としてはMATLABと一緒。
- だいたい0~1の正規化が他のツール、言語の差異になりやすいが、今回は関係ない。
【余談】アフィン変換とニューラルネットワークの関係性?
- 余談として畳み込みニューラルネットワークと畳み込み演算、アフィン変換の関連性を説明。
- 畳み込み層と畳み込み演算は割とそのまんまでわかりやすい。
- 全結合層の前にニューロン1個の演算を数式で表現。
- ニューロンを複数並べたときの数式を書きだした。
- それとアフィン変換の同次座標系の数式を比較。
- 全結合層は別名でアフィン層。
アフィン変換をする上での問題
- アフィン変換後にまだら模様になる問題がある。
- 発生原因は、変換元のピクセルだけでは変換先ピクセルを埋めきれないとき。
- 一般的な補間方法があるが、もっとシンプルな方法を採用する予定。
- まだら模様対策のシンプルなやつを確認。
- アフィン逆変換を使う。
- アフィン逆変換は、アフィン変換の式を変形しただけ。
- アフィン行列が逆行列になる。
- 各種アフィン変換とアフィン行列の説明。
- 伸縮、移動、回転、剪断。
- 回転は回転行列を使ってるので少しわかりにくい。
- よって、別途説明。
- 回転行列概要をWikipediaより引用。
- 動く点Pで回転移動の雰囲気を察する。
- cos,sinを使って直交座標へ。
- 基本ベクトルの変化を元に回転のイメージを得る。
- x軸、y軸の回転を合わせて行列へ。
- これが回転行列。
- アフィン変換のプログラムの流れを確認。
- 中心を0とした座標系の生成。
- 3次元ベクトル配列の生成。
- アフィン変換を一括で行うため。
- アフィン変換のプログラミングに向けてを再確認。
- 画像と同一形状の2次元配列に変換元座標配列を生成。
- 変換元の座標系-1~1をピクセル位置に変換。
- 元画像と変換元座標を元に変換先へコピー。
アフィン変換をプログラムで実現
MATLAB
- MATLABでアフィン変換の伸縮を実施。
- 問題無く動作。
- 他のアフィン変換も動くはずだが、別途実験予定。
Python
- Python(NumPy)でアフィン変換の伸縮を実施。
- 問題無く動作。
- 配列の次元の辻褄あわせのためリストのアンパック仕様を利用している。
- no.blockなどの行列結合でもOK。
Scilab
- Scilabでアフィン変換の伸縮を実施。
- 問題無く動作。
- 環境によってはメモリ不足問題が起きる。
- 画像サイズを小さくするなどで対応が必要。
Julia
- Juliaでアフィン変換の伸縮を実施。
- 問題無く動作。
- meshgridが無いので該当関数を自作。
アフィン行列の合成
- アフィン行列の合成できる。
- 試しに回転アフィンと移動アフィンの合成の雰囲気。
- 実施したい行列が後ろから並ぶ感じ。
- 行列の結合法則を利用して計算自体は前方から実施可能。
- 行列の結合法則について説明。
- 結合法則の前にΣの性質についての説明と証明。
- 総和の順序を入れ替えても等しいという性質。
- 行列の結合法則を証明。
- サイズの証明と任意成分の証明に分かれる。
- ともに証明ができ、行列の結合法則は成立する。
- アフィン逆行列のアルゴリズムを使用している都合、逆行列の結合法則にも気を付ける必要がある。
- アフィン行列の結合を想定したアフィン逆変換の式を書き出し。
- 行列結合後に逆行列する分には問題なさそうだが、個別に行列を管理する場合はいろいろ確認&証明が必要そう。
- 「行列の積の逆行列」と「逆行列の積」の関係性を証明。
- 逆行列の定義を利用して証明。
- 最終的にはすべて単位行列になるので等しいという証明方法になる。
- いままで証明してきたものを再確認。
- 上記を利用して、アフィン逆変換の合成を各アフィン行列単体で管理できる形状に変形。
MATLAB
- MATLABでアフィン行列の合成を確認。
- 問題無く動作。
- 回転行列内の三角関数に渡す角度は度数法ではなく弧度法。
- 180で割ってπを掛ける。
- 変換しない際は単位行列になるようにしておけば、掛けても影響はない。
Python
- Python(NumPy)でアフィン行列の合成を実施。
- 問題無く動作。
- 三角関数ははNumPyが持っているものを使用。
- 他のライブラリも三角関数を持っていることが多い。
- 精度の違い等があるかもしれないが調べてない。
- 他のライブラリも三角関数を持っていることが多い。
Scilab
- Scilabでアフィン行列の合成を実施。
- 問題無く動作した。
- Scilabの変数名、関数名の文字数は最大で24文字。
Julia
- Juliaでアフィン行列の合成を実施。
- 問題無く動作した。
- 毎度のことながらmeshgridは自作関数。
- 毎度のことながら2回目以降の実行処理速度は最速。
- 同じようなことを繰り返しで実行、試行錯誤する場合は便利。
射影変換
- 今回から射影変換に突入。
- 射影変換はアフィン変換の拡張と言われいるが、理屈としては異なるもの。
- 結果的な数式が似ており、アフィン行列で射影変換を行うとアフィン変換が実現できてしまうのが理由と思われる。
- Wikipediaの意味不明な説明を参照。
- 射影変換で出来ることを確認。
- 現実世界での利用方法を紹介。
- 射影変換は四隅の点をどこに移動させるかという変換。
- 長方形から台形、台形から長方形、台形から台形。
- 射影変換の理屈を把握するための流れを記載。
- 大まかな理屈について説明。
- 大まかな理屈を座標変換で表現したパターンで説明。
- 基本ベクトルと基底ベクトルについて説明。
- 元画像平面を3次元空間で表現した場合の式を説明。
- ここで基本ベクトル、基底ベクトルの話が出てくる。
- 「3次元空間を地面平面に落とし込む」
- 高さwのパラメータが重要で、これの影響でアフィン変換ではできなかった台形の対応が可能となる。
- 射影変換を行う一連の座標変換再掲。
- 上記を代入やらしてまとめる。
- さらに、パラメータiで全体を割って変形。
- パラメータ数を9個から8個に減らす。これが後々効いてくる。
- 射影変換の方程式を変形。
- いい感じにキレイになった。
- キレイになった方程式を行列表現へ。
- 射影変換とアフィン変換との関係性について
- 概念は異なるが、行列表現がそっくりなため、射影変換はアフィン変換の拡張と言える。
- パラメータg,hを0にするとアフィン変換と全く同一の式になる。
- 各係数を求めるために式を変形。
- 自明な定数は変換元座標と変換先座標。
- 上記を元に8個の変数を求める8個の連立方程式を作成。
- 射影変換の係数を求める連立方程式を行列表現に。
- これにより、逆行列を使えば一撃で係数が求まる。
- あとは各係数を射影変換行列に居れればOK。
- 射影変換の処理の流れを説明。
- 注意点としては射影変換だとまだら模様問題が起きるので、実際には射影逆変換のアルゴリズムを使用する。
- 射影逆変換について説明。
- 射影変換を元にx,yについて解く式に変形
- sの扱いについて説明。
MATLAB
- MATLABで射影変換を実施。
- 処理はアフィン変換の時のモノを流用。
- 射影変換のsの部分を追加で解決しているのみ。
Python
- Python(NumPy)で射影変換を実施。
- アフィン変換が出来ていれば、射影変換の処理を作るのはそれほど難しくない。
Scilab
- Scilabで射影変換実施。
- 基本的にはMATLABと一緒で、射影変換のsを解決するコードを追加すればOK。
Julia
- Juliaで射影変換実施。
- 基本的にはMATLABと一緒で、射影変換のsを解決するコードを追加すればOK。
射影変換(台形→長方形)
- 射影変換で長方形から台形への変換はやった。
- 台形から長方形への変換もできるはず。
- 画像での雰囲気を確認。
- パラメータでの雰囲気を確認。
- 台形から長方形にする際に引き延ばした部分の画像は荒くなる。
- 射影変換に限らず、引き延ばしが発生する座標変換では必ず起きる問題。
- プログラム化自体は以前のものを使い回し。
- 変換元、変換先のパラメータが変わるくらい。
MATLAB
- MATLABで射影変換の台形から長方形の変換を実施。
- 想定通り変換。
- 画像は荒くなるが想定通り。
- 変換元、変換先パラメータを調整するだけで実現可能。
Python
- Python(NumPy)で射影変換の台形から長方形の変換を実施。
- 想定通り変換。
- コードの流れと構成はMATLAB時のコードと一緒なため、パラメータ調整箇所も一緒。
Scilab
- Scilabで射影変換の台形から長方形の変換を実施。
- 想定通り変換。
- コードの流れと構成及び文法的にもMATLAB時のコードと一緒なため、パラメータ調整箇所も一緒。
Julia
- Juiaで射影変換の台形から長方形の変換を実施。
- 想定通り変換。
- コードの流れと構成及び文法的にもMATLAB時のコードと一緒なため、パラメータ調整箇所も一緒。
- 今回は座標変換なため影響はないが色情報の持ち方が256階調ではなく、0~1に正規化されてる点に注意。
射影変換、アフィン変換合成
- 射影変換は数式上はアフィン変換の拡張型。
- 射影変換とアフィン変換の数式を確認。
- 射影変換のgとhが0の場合、アフィン変換と同一の式になる。
- 射影変換のアフィン行列を入れてアフィン変換になるか試そうと画策。
- せっかくなので、射影変換とアフィン変換を合成してみる。
- 合成の組み立て方はアフィン変換の時と同じ。
- 今回の射影変換のアルゴリズムは射影逆変換。
- これに伴い、渡す行列は逆行列。
- 逆行列を個別に渡す場合は、処理したい順に変換行列を渡す。
- これについてはアフィン変換の時に証明済み。
- 射影変換、アフィン変換合成時のパラメータを(テキトーに)決めた。
- 変換後の想定画像を張り付けた。
- 補助線を入れて過程が分かるように。
MATLAB
- 射影変換とアフィン変換の合成をMATLABで実施。
- 問題無く動作。
- 複数の座標変換だが、事前にパラメータを合成することで処理としては一回にまとめられる。
Python
- 射影変換とアフィン変換の合成をPython(NumPy)で実施。
- 問題無く動作。
- 射影変換にアフィン変換行列を渡せば、アフィン変換ができることを知っていればOK。
Scilab
- 射影変換とアフィン変換の合成をScilabで実施。
- メモリ不足問題に直面しやすいが一応動作した。
- 行列定義の仕方はMATLABと一緒なので、コピペした。
Julia
- 射影変換とアフィン変換の合成をJuliaで実施。
- 問題無く動作した。
- 行列の定義の記述はMATLABと一緒なのでコピペ。
- すごく似ているが故にハマることもある。
まとめ
- 第4章修了。
- 基本的には画像処理関連。
- 一個一個変換するのではなく、変換パラメータを合成して変換処理は一回で済ます考え方が重要。
コメント