はじめに
魚眼カメラで撮影した等距離射影方式の画像を,普通のカメラの中心射影方式のへの変換をするなどの,画像を幾何学的変換することがあります。僕は研究で,中央付近を大きく,外側を小さくする変換をするために使いました。
ここでは,等距離射影方式の画像を中心射影方式の画像に変換する場合を取り上げ,紹介していきます。
なぜCuPyを使うのか
CuPyはNumPyと互換性を持つNVIDIAのGPUで動作することのできるライブラリです。幾何学変換は大量の画素を移動させるので,安直なループで実装すると処理時間が長いです。なので,GPUを使って並列化しようということです。
実装
作成したコード等はここにあります。
import
今回は画像を扱うライブラリにOpenCVを使います。import
するのはこの2つだけです。
|
|
ElementwiseKernel
CuPyで並列化を行うにはElementwiseKernelで簡単に実装できます。詳しくはCuPyのElementwiseKernelで楽にGPUの恩恵を受けるで詳しく説明されています。
入力を変換前の画像img1
とそのサイズsize1
と変換後のサイズsize2
,出力を変換後の画像img2
としています。ここでは簡単にするため入出力する画像は正方形を前提にします。
5–10行目では,変換前後の画素の関係を計算しています。計算式については説明を省きます。
11–13行目で変換後の画像に画素情報を格納しています。入力画像はRGBの3色あるのでこうなっています。変換後のi
1には,変換前のi2, j2
にある画素を格納することになります。
|
|
入出力
1,2行目ではimread
で読み込んだ画像img1
をCuPyの配列に変換しています。3行目では変換後の画像を格納するための空の画像img2_cp
を生成しています。
5行目では,trans_kernel
を呼び出し,GPUを使って並列処理をして変換します。
7,8行目でimg2_cp
をOpenCVで扱えるNumPy形式に変換し,出力します。
|
|
結果
結果は次のようになりました。
魚眼画像 | 補正後 |
---|---|
ひとこと
この記事は僕が研究で使った内容の一部でもありますが,どちらかと言ったら後輩のために書いたメモです。Qiitaに投稿したら僕の中で一番LGTMが多くなったんですよね。やっぱり変人が好む物を書くより,一般的でメジャーな物の方がいいんですね。
文献
- geometric-transformation (GitHub)
- CuPyのElementwiseKernelで楽にGPUの恩恵を受ける(Qiita)
- CuPyを使った画像の幾何学変換with OpenCV (Qiita)
-
i
は2次元を1次元に変えた状態の座標なので,2次元で表すとi/size2, i%size2
となります。 ↩︎