透視変換を行う

透視変換とは 変換前後の4点を指定し 画像を変換することです。画像の回転が3点を指定して変換するのに対し4点になるわけです。
OpenCvでは次の手順で行います。
1)変換前後の座標をもとにgetPerspectiveTransformで変換行列を求める。
public static Mat getPerspectiveTransform(Mat src, Mat dst)
Mat src: 変換前の4点を示す マトリックス CvType.CV_32F
 Mat dst: 変換後の4点を示す マトリックス CvType.CV_32F
src およびdstのCv_TypeはCV_32F以外はエラーになります。
2)変換行列用いて warpPerspective で画像を変換する。
static void warpPerspective(Mat src, Mat dst, Mat M, Size dsize)
static void warpPerspective(Mat src, Mat dst, Mat M, Size dsize, int flags)
static void warpPerspective(Mat src, Mat dst, Mat M, Size dsize, int flags, int borderMode)
static void warpPerspective(Mat src, Mat dst, Mat M, Size dsize, int flags, int borderMode, Scalar borderValue)
Matsrc: 変換前の画像: 変換後の画像
 Mat M : 1)で求めた変換行列
 int desize : 変換する大きさ
 第5引数以降は 『画像を回転する』と同様なので そちらを参照してください。

多くのサンプルでは、遠近法っぽい効果を出すサンプルが多いのですが、今回は逆に、実際にカメラで撮影した若干ひずんだ図形を四角に加工することを試してみました。

 もとの画像 

ちょっと見えにくいですが、
赤い十字で示した (52,38)(18,296)(474,293)(446,58)の4点を 
青い十字で示した (18,38)(18,296)(474,296)(474,38)に変換して 図形の歪を取ってみたいと思います。
 (この座標はペイントを使って手作業で拾いました)

 コーディング 
//変換元座標設定
float srcPoint[] = new float[]{52, 38, 18, 296, 474, 293, 446, 58};
Mat srcPointMat = new Mat(4,2,CvType.CV_32F);
srcPointMat.put(0, 0,srcPoint );
//変換先座標設定
float dstPoint[] = new float[]{18, 38, 18, 296, 474, 296, 474, 38 };
Mat dstPointMat = new Mat(4,2,CvType.CV_32F);
dstPointMat.put(0, 0,dstPoint );
//変換行列作成
Mat r_mat = Imgproc.getPerspectiveTransform(srcPointMat, dstPointMat);
//図形変換処理
Mat dstMat = new Mat(mat.rows(),mat.cols(),mat.type());
Imgproc.warpPerspective(mat, dstMat, r_mat, dstMat.size(),Imgproc.INTER_LINEAR);
 処理結果 

図形の歪がとれて碁盤の線が直行しているように見えます。成功です!!!

 by Android2.2 with OpenCv 2.3.1 for Android   
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする