前回 ImgprocクラスのメソッドgetAffineTransform・warpAffineを使って 画像を回転する実験をしました。今回は、前回省略した第五引数以降の引数についてどのような効果があるか実験します。
static void warpAffine(Mat src, Mat dst, Mat M, Size dsize, int flags, int borderMode, Scalar borderValue)
Mat src: 変換前画像
Mat dst: 変換後画像
Mat M: アフィン変換行列
Size dsize: アフィン変換対象とするサイズ(幅・高さ)
int flags: 補完手法
int borderMode: ピクセル外挿手法
Scalar borderValue: 定数境界モードで利用されるピクセル値.デフォルトでは 0
flags : 補完手法 INTER_NEAREST INTER_LINEAR INTER_AREA INTER_CUBIC INTER_LANCZOS4
(画像サイズの変更参照)
これらとともに WARP_INVERSE_MAPを指定すると Mが逆変換(dst–>src)であることを示します。
borderMode : 画像を回転する際 空き領域となるピクセルの扱いを指定します。
BORDER_REPLICATE 画像境界の値を複製してコピー
BORDER_CONSTANT borderValueで指定したピクセル値
BORDER_REFLECT 画像境界で反射するようにコピー
BORDER_WRAP 画像自身を繰り返しコピー
BORDER_REFLECT_101 画像境界で反射するようにコピー
BORDER_REFLECT101 画像境界で反射するようにコピー
BORDER_DEFAULT 画像境界で反射するようにコピー
BORDER_TRANSPARENT 元画像を変更しない
BORDER_REFLECT・BORDER_REFLECT_101・BORDER_REFLECT101・BORDER_DEFAULTは同じ結果になりました。
borderValue : borderModeで「BORDER_CONSTANT」を選択した際に利用するピクセル値を指定します。 デフォルトでは、borderMode=BORDER_CONSTANT borderValue=ゼロです。
指定なしの状態 |
Imgproc.warpAffine(srcMat, dstMat, rot_mat,dstMat.size());
上段:変換前画像
下段:変換後画像 幅・高さを変換前画像の高さにあわせ、変換後の領域がわかるよう 白線で囲ってあります。
flags |
補完方法は、画像の拡大・縮小と同じだと思いますので、WARP_INVERSE_MAPだけ実験します。一旦変換し、さらに回転した画像を逆変換してみます。
上段:変換した画像
Imgproc.warpAffine(srcMat, dstMat1, rot_mat,dstMat1.size(),Imgproc.INTER_LINEAR );
下段:さらに逆変換した画像
Imgproc.warpAffine(dstMat1, dstMat2, rot_mat,dstMat2.size(),Imgproc.INTER_LINEAR|Imgproc.WARP_INVERSE_MAP);
一回目の変換処理で、出力領域外になってしまった部分を除き きれいに元の位置に戻っていることがわかります。
borderMode |
上段:BORDER_REPLICATE
Imgproc.warpAffine(srcMat, dstMat1, rot_mat,dstMat1.size(),Imgproc.INTER_LINEAR,
Imgproc.BORDER_REPLICATE );
境界に接しているピクセル値をそのまま空の部分にコピーしています。
下段:BORDER_CONSTANT
Imgproc.warpAffine(srcMat, dstMat2,rot_mat,dstMat2.size(),Imgproc.INTER_LINEAR,
Imgproc.BORDER_CONSTANT,new Scalar(128,0,128));
空の部分が Scalar(128.0.128) ⇒ RGB(128,0,128) ⇒ 紫 で埋まっています。
上段:BORDER_REFLECT
Imgproc.warpAffine(srcMat, dstMat1, rot_mat,dstMat1.size(),Imgproc.INTER_LINEAR,
Imgproc.BORDER_REFLECT);
境界が鏡のようなっています。
BORDER_REFLECT・BORDER_REFLECT_101・BORDER_REFLECT101・BORDER_DEFAULTは同じ結果になりました。
下段:BORDER_WRAP
Imgproc.warpAffine(srcMat, dstMat2,rot_mat,dstMat2.size(),Imgproc.INTER_LINEAR,
Imgproc.BORDER_WRAP);
画像が繰り返しコピーされています。
BORDER_TRANSPARENT
Imgproc.warpAffine(srcMat, dstMat1, rot_mat,dstMat1.size(),Imgproc.INTER_LINEAR,
Imgproc.BORDER_TRANSPARENT);
変換先Matを生成する際
Mat dstMat1 = new Mat(srcMat.rows(),srcMat.rows(),srcMat.type(),new Scalar(255, 192, 180));
として あらかじめ RGB:ff69b4(hot Pink)で初期化してあります。このピクセル値がそのまま残っています。
by Android2.2 with OpenCv 2.3.1 for Android |