void QUickdemo::roate_demo(Mat& image)
{
Mat dst, M;
int w = image.cols;
int h = image.rows;
M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);--M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);:使用getRotationMatrix2D函数生成一个旋转矩阵M。这个函数的参数分别是旋转中心(这里是图像的中心,即Point2f(w / 2, h / 2))、旋转角度(这里是 45 度)和缩放因子(这里是 1.0,表示不进行缩放)。
重新计算新图像尺寸
double cos = abs(M.at<double>(0, 0));
double sin = abs(M.at<double>(0, 1));
--double cos = abs(M.at<double>(0, 0)); double sin = abs(M.at<double>(0, 1));:从旋转矩阵中获取对应的值,用于计算新图像的宽度和高度。其中的cos和sin是计算新图像的重要数值。
在这段代码中,从M.at<double>(0, 0)和M.at<double>(0, 1)获取值是因为旋转矩阵的结构决定的。
一个 2D 旋转矩阵通常具有以下形式:
| cosθ -sinθ |
| sinθ cosθ |
其中,cosθ在第一行第一列(对应(0, 0)),sinθ在第一行第二列(对应(0, 1))。
代码中通过获取这两个位置的值,可以得到与旋转角度相关的余弦值和正弦值,用于后续计算旋转后图像的新宽度和新高度等操作。
int nw = cos * w + sin * h;
int nh = cos * h + sin * w;
--
int nw = cos * w + sin * h; int nh = cos * h + sin * w;:计算旋转后的图像的新宽度nw和新高度nh。
M.at<double>(0, 2) += (nw / 2 - w / 2);
M.at<double>(1, 2) += (nh / 2 - h / 2);
这两行代码的作用是调整旋转矩阵M中的平移量,以确保旋转后的图像中心与新图像的中心对齐。
1. M.at<double>(0, 2) += (nw / 2 - w / 2);
• M.at<double>(0, 2)代表旋转矩阵M中第一行第三列的元素,它控制着图像在水平方向上的平移量。
• nw / 2是新图像宽度的一半,w / 2是原始图像宽度的一半。计算nw / 2 - w / 2得到的是新图像中心与原始图像中心在水平方向上的偏移量。
• 将这个偏移量加到M.at<double>(0, 2)上,就调整了水平方向的平移量,使得旋转后的图像在水平方向上的中心与新图像的中心对齐。
2. M.at<double>(1, 2) += (nh / 2 - h / 2);
• 同理,M.at<double>(1, 2)是旋转矩阵M中第二行第三列的元素,控制着图像在垂直方向上的平移量。
• nh / 2是新图像高度的一半,h / 2是原始图像高度的一半。计算nh / 2 - h / 2得到新图像中心与原始图像中心在垂直方向上的偏移量。
• 将这个偏移量加到M.at<double>(1, 2)上,调整垂直方向的平移量,使得旋转后的图像在垂直方向上的中心与新图像的中心对齐。
warpAffine(image, dst, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 0, 0));
这行代码使用 OpenCV 库中的 warpAffine 函数对图像进行仿射变换(这里主要是旋转)。
1. image:
• 这是输入的原始图像,即要进行旋转操作的图像。
2. dst:
• 这是输出的目标图像,函数执行后,经过旋转后的图像将存储在这个变量中。
3. M:
• 这是一个 2x3 的变换矩阵,它描述了如何对图像进行变换,包括旋转、平移、缩放等操作。在前面的代码中,这个矩阵是通过 getRotationMatrix2D 函数生成,并根据旋转角度和图像尺寸进行了调整。
4. Size(nw, nh):
• 这指定了输出图像的大小,其中 nw 是新图像的宽度,nh 是新图像的高度,这两个值在前面的计算中已经根据旋转角度和原始图像尺寸确定。
5. INTER_LINEAR:
• 这是插值方法的标志,表示在图像变换过程中使用线性插值。线性插值可以在图像放大或缩小时提供相对平滑的效果。
6. 0:
• 这是边界外推法的标志,这里表示使用默认的边界外推方法。
7. Scalar(255, 0, 0):
• 这是用于填充边界的颜色值,这里表示用蓝色(R = 255,G = 0,B = 0)填充边界。如果在图像变换过程中出现了新的边界区域,这些区域将用指定的颜色填充。
imshow("tt", dst);
}