アフィン変換(パラメータを与えて,変換行列を求める)
C
#include <cv.h> #include <highgui.h> int main(int argc, char **argv) { double angle = -45.0, scale = 1.0; IplImage *src_img = 0, *dst_img = 0; CvMat *affine_matrix; CvPoint2D32f center; CvPoint pt1, pt2; CvRect rect; char *imagename; // (1)load a specified file as a 3-channel color image, // set its ROI, and allocate a destination image imagename = argc > 1 ? argv[1] : "../image/building.png"; src_img = cvLoadImage(imagename, CV_LOAD_IMAGE_COLOR); if(src_img == 0) return -1; dst_img = cvCloneImage(src_img); // (2)set ROI rect.x = cvRound(src_img->width * 0.25); rect.y = cvRound(src_img->height * 0.25); rect.width = cvRound(src_img->width * 0.5); rect.height = cvRound(src_img->height * 0.5); cvSetImageROI(src_img, rect); // (3)with specified three parameters (angle, rotation center, scale) // calculate an affine transformation matrix by cv2DRotationMatrix affine_matrix = cvCreateMat(2, 3, CV_32FC1); center = cvPoint2D32f(src_img->width * 0.25, src_img->height * 0.25); cv2DRotationMatrix(center, angle, scale, affine_matrix); // (4)rotate the image by warpAffine taking the affine matrix cvWarpAffine(src_img, dst_img, affine_matrix, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(255)); // (5)reset ROI, then show source and destination image with a rectangle indicating ROI cvResetImageROI(src_img); cvResetImageROI(dst_img); pt1 = cvPoint(rect.x, rect.y); pt2 = cvPoint(rect.x + rect.width, rect.y + rect.height); cvRectangle(src_img, pt1, pt2, CV_RGB(255, 0, 255), 2, 8, 0); cvNamedWindow("src", CV_WINDOW_AUTOSIZE); cvNamedWindow("dst", CV_WINDOW_AUTOSIZE); cvShowImage("src", src_img); cvShowImage("dst", dst_img); cvWaitKey(0); cvDestroyWindow("src"); cvDestroyWindow("dst"); cvReleaseImage(&src_img); cvReleaseImage(&dst_img); cvReleaseMat(&affine_matrix); return 1; }
// (1)画像の読み込み(カラー),出力用画像を複製します.
指定されたfファイルを3チャンネルのカラー画像として読み込みます.読み込みに失敗した場合,return -1 で終了します.この入力画像を cvCloneImage により複製し,出力用の画像領域を確保します.また,入力画像と同じサイズ,同じビット深度の出力画像領域を確保します.
// (2)ROIを設定します.
このサンプルでは,画像の一部に対してアフィン変換を行うので,そのためのROIを cvSetImageROI により設定します.ここでは,画像の中心領域(1/4)をROIとしています.
// (3)与えられたパラメータを元に,アフィン変換行列を求めます.
ここでは,回転角度,回転中心,スケーリング係数の3種のパラメータを与え,そこから cv2DRotationMatrix を用いてアフィン変換行列を求めます.また,「アフィン変換(変換前後の3点の組を与えて,変換行列を求める)」の例も参考にしてください.
// (4)アフィン変換行列を用いて画像を回転します.
(3) で求められた行列を用いて, cvWarpAffine によって画像のアフィン変換を行います.
// (5)ROIをリセットし,画像を表示します.
設定したROIを cvResetImageROI によりリセットし,ROIを表す矩形を元画像上に描画します.それを,アフィン変換を施した結果画像と共に表示します.何かキーが押されるまで待ちます.
C++
#include <cv.h> #include <highgui.h> using namespace cv; int main(int argc, char **argv) { // (1)load a specified file as a 3-channel color image, // set its ROI, and allocate a destination image const string imagename = argc > 1 ? argv[1] : "../image/building.png"; Mat src_img = imread(imagename); if(!src_img.data) return -1; Mat dst_img = src_img.clone(); // (2)set ROI Rect roi_rect(cvRound(src_img.cols*0.25), cvRound(src_img.rows*0.25), cvRound(src_img.cols*0.5), cvRound(src_img.rows*0.5)); Mat src_roi(src_img, roi_rect); Mat dst_roi(dst_img, roi_rect); // (2)With specified three parameters (angle, rotation center, scale) // calculate an affine transformation matrix by cv2DRotationMatrix double angle = -45.0, scale = 1.0; Point2d center(src_roi.cols*0.5, src_roi.rows*0.5); const Mat affine_matrix = getRotationMatrix2D( center, angle, scale ); // (3)rotate the image by warpAffine taking the affine matrix warpAffine(src_roi, dst_roi, affine_matrix, dst_roi.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar::all(255)); // (4)show source and destination images with a rectangle indicating ROI rectangle(src_img, roi_rect.tl(), roi_rect.br(), Scalar(255,0,255), 2); namedWindow("src", CV_WINDOW_AUTOSIZE); namedWindow("dst", CV_WINDOW_AUTOSIZE); imshow("src", src_img); imshow("dst", dst_img); waitKey(0); return 0; }
// (1)画像の読み込み(カラー),出力用画像を複製します.
指定されたfファイルを3チャンネルのカラー画像として読み込みます.読み込みに失敗した場合,return -1 で終了します.この入力画像を Mat.clone メソッドにより複製し,出力用の画像領域を確保します.また,入力画像と同じサイズ,同じビット深度の出力画像領域を確保します.
// (2)ROIを設定します.
このサンプルでは,画像の一部に対してアフィン変換を行うので,そのためのROIを作成します.ここでは,画像の中心領域(1/4)をROIとしています.
// (3)与えられたパラメータを元に,アフィン変換行列を求めます.
ここでは,回転角度,回転中心,スケーリング係数の3種のパラメータを与え,そこから getRotationMatrix2D を用いてアフィン変換行列を求めます.また,「アフィン変換(変換前後の3点の組を与えて,変換行列を求める)」の例も参考にしてください.
// (4)アフィン変換行列を用いて画像を回転します.
(3) で求められた行列を用いて, warpAffine によって画像のアフィン変換を行います.
// (5)ROIを表す矩形を描画し,画像を表示します.
設定したROIを表す矩形を元画像上に描画し,アフィン変換を施した結果画像と共に表示します.何かキーが押されるまで待ちます.