# OpenCV3入门（九）图像几何变换

2019/04/10 10:10

## 1、图像缩放

``````CV_EXPORTS_W void resize( InputArray src, OutputArray dst,
Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR );``````

``````img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic9.bmp");
imshow("原图", img);
resize(img, img2, Size(), 0.5, 0.5);
imshow("缩放图1", img2);
resize(img, img3, Size(), 0.8, 0.5);
imshow("缩放图2", img3);``````

resize(img, img2, Size(), 1.2, 1.2);

## 2、图像平移

dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)

``````CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());``````

``````img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic9.bmp", IMREAD_GRAYSCALE);
imshow("原图", img);

// x轴平移20，y轴平移10, 2 * 3矩阵
Mat M = Mat::zeros(2, 3, CV_32FC1);
M.at<float>(0, 0) = 1;
M.at<float>(0, 2) = 20;
M.at<float>(1, 1) = 1;
M.at<float>(1, 2) = 10;
warpAffine(img, img2, M, img.size());
imshow("平移图", img2);``````

## 3、图像旋转

P0旋转b度到P1(x1,y1)，则

x1=L*cos(a+b)=L* cos(a)*cos(b) – L*sin(a)*sin(b) = x0*cos(b) - y0*sin(b)

y1=L*sin(a+b)=L* sin(a)*cos(b) + L*cos(a)*sin(b) = y0*cos(b) + x0*sin(b)

OpenCV内置仿射变换的旋转函数，支持任意点为中心的图像旋转，函数原型为：

CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale );

``````img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic9.bmp");
imshow("原图", img);

Point center = Point(img.cols / 2, img.rows / 2);
Mat m1= getRotationMatrix2D(center, 30, 1.0);
Mat m2 = getRotationMatrix2D(center, 30, 0.7);
Mat m3 = getRotationMatrix2D(center, 30, 1.2);
warpAffine(img, img1, m1, img.size());
warpAffine(img, img2, m2, img.size());
warpAffine(img, img3, m3, img.size());
imshow("img1", img1);
imshow("img2", img2);
imshow("img3", img3);``````

Mat m1= getRotationMatrix2D(center, 180, 1.0);

Mat m2 = getRotationMatrix2D(center, 270, 0.7);

``````Point center = Point(0, 0);

Mat m1= getRotationMatrix2D(center, 30, 1.0);

Mat m2 = getRotationMatrix2D(center,-45, 1.0);``````

m1=

[0.8660254037844387, 0.4999999999999999, 0;

-0.4999999999999999, 0.8660254037844387, 0]

m2=

[0.7071067811865476, -0.7071067811865476, 0;

0.7071067811865476, 0.7071067811865476, 0]

## 4、图像重映射

OpenCV使用remap函数完成重映射功能，函数原型为：

``````CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
InputArray map1, InputArray map2,
int interpolation, int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());``````

``````void update_map(int ind, Mat &map_x, Mat &map_y)
{
for (int i = 0; i < map_x.rows; i++)
{
for (int j = 0; j < map_x.cols; j++)
{
switch (ind)
{
case 0:
if (j > map_x.cols*0.25 && j < map_x.cols*0.75 && i > map_x.rows*0.25 && i < map_x.rows*0.75)
{
map_x.at<float>(i, j) = 2 * (j - map_x.cols*0.25f) + 0.5f;
map_y.at<float>(i, j) = 2 * (i - map_x.rows*0.25f) + 0.5f;
}
else
{
map_x.at<float>(i, j) = 0;
map_y.at<float>(i, j) = 0;
}
break;
case 1:
map_x.at<float>(i, j) = (float)j;
map_y.at<float>(i, j) = (float)(map_x.rows - i);
break;
case 2:
map_x.at<float>(i, j) = (float)(map_x.cols - j);
map_y.at<float>(i, j) = (float)i;
break;
case 3:
map_x.at<float>(i, j) = (float)(map_x.cols - j);
map_y.at<float>(i, j) = (float)(map_x.rows - i);
break;
default:
break;
} // end of switch
}
}
}

int main() {
Mat src = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic9.bmp");
imshow("原图", src);

Mat dst(src.size(), src.type());
Mat map_x(src.size(), CV_32FC1);
Mat map_y(src.size(), CV_32FC1);

update_map(0, map_x, map_y);
remap(src, img1, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("img1", img1);

update_map(1, map_x, map_y);
remap(src, img2, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("img2", img2);

update_map(2, map_x, map_y);
remap(src, img3, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("img3", img3);

update_map(3, map_x, map_y);
remap(src, img4, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("img4", img4);

waitKey();
}``````

remap后的图像：

``````for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
map_x.at<float>(i, j) = j;
map_y.at<float>(i, j) = (float)((-1 * pow(i- src.rows / 2, 2) / pow(src.rows / 2, 2)) + 1) * src.rows;
}
}``````

## 5、参考文献

1、《OpenCV3 编程入门》，电子工业出版社，毛星雨著

2、《学习OpenCV》，清华大学出版社，Gary Bradski， Adrian kaehler著

3、Remapping

https://docs.opencv.org/3.4/d1/da0/tutorial_remap.html

4、OpenCV图像旋转

https://www.cnblogs.com/konglongdanfo/p/9135501.html

https://www.cnblogs.com/pingwen/p/12329168.html

0
0 收藏

0 评论
0 收藏
0