画像の幾何学変換
このサブセクションで述べる関数は,2次元画像の様々な幾何学変換を行います.つまり,画像の内容は変更せずにピクセルグリッドだけを変形し,変形したグリッドを出力画像にマッピングします.実際には,サンプリングによる余計な値や不定な値を排除するために,出力画像から入力画像という逆方向へのマッピングが行われます.つまり,出力画像の各ピクセル
に対して,入力画像中の対応する「ドナー」ピクセルの座標を求め,そのピクセル値をコピーします:
ユーザが正順のマッピング:
を指定した場合,OpenCV の関数は最初に,対応する逆マッピング:
を求めてから上述の式を利用します.
幾何学変換の実際の実装では,最も汎用的な
remap()
から,最も単純で高速な
resize()
まで,上述の式を用いて2つの主な問題を解く必要があります:
- 存在しないピクセルの外挿.
フィルタリング関数
と同様に,ある
に対して,
または
のどちらか,あるいは両方が画像の外側にはみ出してしまう可能性があります.この場合,何らかの外挿手法が必要になります.OpenCVでは,フィルタリング関数の場合と同じく,いくつかの外挿手法が提供されています.さらに別の手法も追加されており,その
BORDER_TRANSPARENT
は,出力画像中の対応するピクセルが全く変更されないことを意味します.
- ピクセル値の内挿.通常
と
は,浮動小数点数(つまり,
は,アフィン変換,透視変換,または半径方向のレンズ歪み係数など)です.よって,小数点座標上に存在するピクセル値が必要になります.最も単純なケースでは,この座標は単に最も近い整数値の座標に丸められ,そこのピクセル値が利用されます.これは,最近傍補間と呼ばれます.しかし,より洗練された
補間手法
を用いることで,より良い結果が得られます.この場合,求められたピクセル
近傍に対して多項式関数をフィッティングし,
における多項式の値を,補間されたピクセル値として利用します.OpenCVでは,複数の補間手法から選択することができます.詳しくは
resize()
を参照してください.
cv::convertMaps
Comments from the Wiki
-
void convertMaps(const Mat& map1, const Mat& map2, Mat& dstmap1, Mat& dstmap2, int dstmap1type, bool nninterpolation=false)
画像変換マップを,ある表現から別の表現へ変換します.
パラメタ: |
- map1 – 1番目の入力マップ.型は CV_16SC2 , CV_32FC1 , CV_32FC2 のいずれか
- map2 – 2番目の入力マップ.型は CV_16SC1 , CV_32FC1 , あるいはそれぞれに対する none (空の行列) のいずれか
- dstmap1 – 1番目の出力マップ. dstmap1type で指定される型, src と同じサイズ
- dstmap2 – 2番目の出力マップ
- dstmap1type – 1番目の出力マップの型. CV_16SC2 , CV_32FC1 あるいは CV_32FC2 のいずれか
- nninterpolation – 最近傍補間,または,より複雑な補間手法に対して,浮動小数点型のマップが利用されるか否かを指定します
|
この関数は,
remap()
用のマップの組を,ある表現から別の表現へ変換します.以下のオプション(
(map1.type(), map2.type())
(dstmap1.type(), dstmap2.type())
)がサポートされます:
-
. これは,最も頻繁に利用される変換処理です.元の浮動小数点型マップ(
remap()
を参照してください)は,よりコンパクトで非常に高速な浮動小数点型の表現に変換されます.1番目の出力配列は丸められた座標値を表し,2番目の出力配列(ただし,
nninterpolation=false
の場合のみ作られます)は,補間テーブルのインデックスを表します.
-
. 上述の場合と同じですが,元のマップは1つの2チャンネル行列に格納されます.
- 逆変換.当然ながら,再構成された浮動小数点型マップは元のマップとは正確には一致しません.
参考:
remap()
,
undisort()
,
initUndistortRectifyMap()
cv::getRectSubPix
Comments from the Wiki
-
void getRectSubPix(const Mat& image, Size patchSize, Point2f center, Mat& dst, int patchType=-1)
画像から,矩形領域のピクセル値をサブピクセル精度で取得します.
パラメタ: |
- src – 入力画像
- patchSize – 抽出される部分のサイズ
- center – 入力画像から抽出される矩形の中心を表す,浮動小数点型の座標.この中心は,画像内に存在しなければいけません
- dst – 抽出される部分.サイズは patchSize で, src と同じチャンネル数になります
- patchType – 抽出されるピクセルのビット深度.デフォルトでは, src のビット深度と同じになります
|
関数
getRectSubPix
は,
src
からピクセルを抽出します:
ここで,非整数の座標におけるピクセル値は,バイリニア補間を用いて取得されます.また,マルチチャンネル画像の各チャンネルは,それぞれ個別に処理されます.矩形領域の中心は,必ず画像内部になければいけませんが,矩形領域の一部が画像外部にはみ出していても構いません.その場合は,画像外にある領域のピクセル値を取得するために,複製境界モード(
borderInterpolate()
を参照してください)が利用されます.
参考:
warpAffine()
,
warpPerspective()
cv::getRotationMatrix2D
Comments from the Wiki
-
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
2次元回転を表すアフィン変換を求めます.
パラメタ: |
- center – 入力画像中にある回転中心
- angle – 度単位で表される回転角度.正の値は反時計回りを意味します(座標原点が,左上コーナーにあると仮定されます)
- scale – 等方性のスケールファクタ
|
この関数は,以下の行列を求める:
ここで
となります.
この変換は,回転中心をそれ自身にマップします.そうしたくない場合は,シフトによる調整を行う必要があります.
参考:
getAffineTransform()
,
warpAffine()
,
transform()
cv::resize
Comments from the Wiki
-
void resize(const Mat& src, Mat& dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
画像のサイズを変更します.
パラメタ: |
- src – 入力画像
- dst – 出力画像.サイズは dsize (0でない場合)か,または src.size() , fx , fy から計算される値になります. dst の型は, src と同じになります
- dsize –
出力画像サイズ.これが0の場合,次のように計算されます:
.
必ず dsize が非0,あるいは fx と fy の両方が非0,でなければいけません
- fx –
水平軸方向のスケールファクタ.これが0の場合,次のように計算されます:
- fy –
垂直軸方向のスケールファクタ.これが0の場合,次のように計算されます:
- interpolation –
補間手法:
- INTER_NEAREST 最近傍補間
- INTER_LINEAR バイリニア補間(デフォルト)
- INTER_AREA ピクセル領域の関係を利用したリサンプリング.画像を大幅に縮小する場合は,モアレを避けることができる良い手法です.しかし,画像を拡大する場合は, INTER_NEAREST メソッドと同様になります
- INTER_CUBIC 4x4 の近傍領域を利用するバイキュービック補間
- INTER_LANCZOS4 8x8 の近傍領域を利用する Lanczos法の補間
|
関数
resize
は,画像
src
を指定されたサイズに縮小,あるいは拡大します.
dst
の型やサイズは考慮されないことに注意してください.その代わり,型やサイズは
src
,
dsize
,
fx
そして
fy
から求められます.あらかじめ用意しておいた
dst
とぴったり同じになるように
src
のサイズを変更したい場合,次のような関数呼び出しができます:
// dsize=dst.size(); を明示的に指定します. fx と fy はここから計算されます.
resize(src, dst, dst.size(), 0, 0, interpolation);
各方向に二分の一に縮小したい場合は,次のような関数呼び出しができます:
// fx とfy を定して,関数に出力画像サイズを計算させます.
resize(src, dst, Size(), 0.5, 0.5, interpolation);
参考:
warpAffine()
,
warpPerspective()
,
remap()
.
cv::warpAffine
Comments from the Wiki
-
void warpAffine(const Mat& src, Mat& dst, const Mat& M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
画像のアフィン変換を行います.
パラメタ: |
- src – 入力画像
- dst – サイズが dsize で src と同じタイプの出力画像
- M – の変換行列
- dsize – 出力画像のサイズ
- flags – 補間手法( resize() を参照してください)と, M が逆変換( dst src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
- borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode = BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
- borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
|
関数
warpAffine
は,指定された行列を用いて入力画像を変換します:
ここでは,フラグ
WARP_INVERSE_MAP
が設定されています.そうでない場合は,まず
invertAffineTransform()
によって逆変換が求められ,それが上式の
M
の代わりに利用されます.
この関数は,置換モードでは動作しません.
参考:
warpPerspective()
,
resize()
,
remap()
,
getRectSubPix()
,
transform()
cv::warpPerspective
Comments from the Wiki
-
void warpPerspective(const Mat& src, Mat& dst, const Mat& M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
画像の透視変換を行います.
パラメタ: |
- src – 入力画像
- dst – サイズが dsize で src と同じタイプの出力画像
- M – の変換行列
- dsize – 出力画像のサイズ
- flags – 補間手法( resize() を参照)と, M が逆変換( dst src )であることを意味するオプションフラグ WARP_INVERSE_MAP の組み合わせ
- borderMode – ピクセル外挿手法. borderInterpolate() を参照してください. borderMode=BORDER_TRANSPARENT の場合,入力画像中の「はずれ値」に対応する出力画像中のピクセルが,この関数では変更されないことを意味します
- borderValue – 定数境界モードで利用されるピクセル値.デフォルトでは 0 です
|
関数
warpPerspective
は,指定された行列を用いて入力画像を変換します:
ここでは,フラグ
WARP_INVERSE_MAP
が設定されています.そうでない場合は,まず
invert()
によって逆変換が求められ,それが上式の
M
の代わりに利用されます.
この関数は,置換モードでは動作しない.
参考:
warpAffine()
,
resize()
,
remap()
,
getRectSubPix()
,
perspectiveTransform()