介绍简单的图像几何变换,主要包括缩放,移动,旋转,仿射变换,透视变换等
一、扩展缩放
扩展缩放只改变图像的尺寸大小。OpenCV提供了函数resize()可以实现这个功能。可以通过指定缩放因子也可以直接指定尺寸来设置图像的大小。扩展缩放时,可以选择不同的插值方法,扩展时推荐使用INTER_CUBIC和INTER_LINEAR,缩放时推荐使用INTER_AREA。默认情况下,扩展和缩放使用的都是INTER_LINEAR。
void resize(InputArray src, OutputArray dst, Size dsize,
double fx=
0,
double fy=
0,
int interpolation=INTER_LINEAR )
其中:
src, dst分别为原图像和扩展缩放后的图像。dsize为缩放后图像的大小fx, fy分别为X和Y方向的缩放因子,dszie和fx, fy不能同时为0interpolation,插值方法,有以下几种:
INTER_NEAREST - 最近邻插值INTER_LINEAR - 线性插值(默认)INTER_AREA - 区域插值INTER_CUBIC - 三次样条插值INTER_LANCZOS4 - Lanczos插值
Mat
image = imread(
"1.jpg",CV_LOAD_IMAGE_UNCHANGED);
namedWindow(
"im1");
imshow(
"im1",
image);
Mat output;
resize(
image,output,Size(),
2,
2,INTER_CUBIC);
namedWindow(
"im2");
imshow(
"im2",output);
二、平移
平移是将图像移动到其它位置,可以使用OpenCV提供的函数wrapAffine达到目的。如果想让图像沿(x,y)方向移动,移动的距离为(tx,ty),则可以以下面的方式构建移动矩阵,然后作为参数传递给wrapAffine。
M=[1001txty]
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize,
int flags=INTER_LINEAR,
int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar())
其中:
src, dst分别为输入图像和输出图像M是变换矩阵flags是插值算法
enum InterpolationFlags{
/** nearest neighbor interpolation */
INTER_NEAREST =
0,
/** bilinear interpolation */
INTER_LINEAR =
1,
/** bicubic interpolation */
INTER_CUBIC =
2,
/** resampling using pixel area relation. It may be a preferred method for image decimation, as
it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST
method. */
INTER_AREA =
3,
/** Lanczos interpolation over 8x8 neighborhood */
INTER_LANCZOS4 =
4,
/** mask for interpolation codes */
INTER_MAX =
7,
/** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
source image, they are set to zero */
WARP_FILL_OUTLIERS =
8,
/** flag, inverse transformation
For example, polar transforms:
- flag is __not__ set: \f$dst( \phi , \rho ) = src(x,y)\f$
- flag is set: \f$dst(x,y) = src( \phi , \rho )\f$
*/
WARP_INVERSE_MAP =
16
};
boderMode是边界处理方式
enum BorderTypes {
BORDER_CONSTANT =
0, //!<
`iiiiii|abcdefgh|iiiiiii
` with some specified
`i`
BORDER_REPLICATE =
1, //!<
`aaaaaa|abcdefgh|hhhhhhh
`
BORDER_REFLECT =
2, //!<
`fedcba|abcdefgh|hgfedcb
`
BORDER_WRAP =
3, //!<
`cdefgh|abcdefgh|abcdefg
`
BORDER_REFLECT_101 =
4, //!<
`gfedcb|abcdefgh|gfedcba
`
BORDER_TRANSPARENT =
5, //!<
`uvwxyz|absdefgh|ijklmno
`
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED =
16 //!< do
not look outside of ROI
}
使图片在X方向和Y方向各移动50个像素
Mat kernel(
2,
3,CV_32F,Scalar(
0));
kernel.at<
float>(
0,
0) =
1;
kernel.at<
float>(
1,
1) =
1;
kernel.at<
float>(
0,
2) =
50;
kernel.at<
float>(
1,
2) =
50;
warpAffine(
image,output,kernel,Size(
image.cols,
image.rows));
三、旋转
对一个图像旋转角度
θ
,需要用到如下形式的旋转矩阵:
M=[cosθsinθ−sinθcosθ]
OpenCV允许在任意地方进行旋转,旋转矩阵的形式应更新为更加通用的形式:
M=[α−ββα(1−α)∗center.x−β∗center.yβ∗center.x+(1−α)∗center.x]
其中:
α=scale∗cosθ
β=scale∗sinθ
OpenCV提供了一个函数用于构建上述的旋转矩阵:
Mat getRotationMatrix2D(Point2f center,
double angle,
double scale)
center: 旋转中心angle:旋转弧度,注意要将角度转换成弧度scale: 缩放比例
double degree =
30;
double angle = degree * CV_PI /
180.;
double a =
sin(angle), b =
cos(angle);
int width = image.cols;
int height = image.rows;
int width_rotate =
int(height *
fabs(a) + width *
fabs(b));
int height_rotate =
int(width *
fabs(a) + height *
fabs(b));
Point center = Point(image.cols /
2, image.rows /
2);
Mat map_matrix = getRotationMatrix2D(center, degree,
1.0);
map_matrix.at<
double>(
0,
2) += (width_rotate - width) /
2;
map_matrix.at<
double>(
1,
2) += (height_rotate - height) /
2;
Mat outout;
warpAffine(image, output, map_matrix, Size(width_rotate, height_rotate),INTER_CUBIC | CV_WARP_FILL_OUTLIERS, BORDER_CONSTANT, Scalar(
0));
四、仿射变换
Point2f src[
3] = {Point2f(
50,
50),Point2f(
200,
50),Point2f(
50,
200)};
Point2f dst[
3] = {Point2f(
10,
100),Point2f(
200,
50),Point2f(
100,
250)};
Mat kernel = getAffineTransform(src,dst);
warpAffine(
image,output,kernel,Size(
image.cols,
image.rows));
五、透视变换
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize,
int flags=INTER_LINEAR,
int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar())
示例:
Point2f src[
4] = {Point2f(
100,
50),Point2f(
100,
550),Point2f(
350,
50),Point2f(
350,
550)};
Point2f dst[
4] = {Point2f(
100,
100),Point2f(
100,
350),Point2f(
300,
50),Point2f(
350,
450)};Mat kernel = getPerspectiveTransform(src,dst);
warpPerspective(
image,output,kernel,Size(
image.cols,
image.rows));
转载请注明原文地址: https://ju.6miu.com/read-33149.html