OpenCV基础(5)使用OpenCV进行图像旋转和平移

如今,图像编辑变得越来越受欢迎,因为手机拥有这种内置功能,可以让你对图像进行裁剪、旋转以及更多操作。

在这篇文章中,我们将探索和学习这些图像编辑技术。具体来说,我们将学习如何:

  • 1.旋转图像
  • 2平移或移动图像内容

1.基本图像变换操作

图像的旋转和平移是图像编辑中最基本的操作之一。两者都属于广义的仿射变换。因此,在学习更复杂的转换之前,您应该首先学习使用OpenCV中的函数旋转和平移图像。
让我们先看看下面的代码,它将用于使用OpenCV执行图像旋转。在这篇文章的其余部分,我们将详细讨论每一行,以及图像的平移。在这篇文章的结尾,你会对下面的代码有一个很好的理解。
(1)Python

import cv2

# 读取图片
image = cv2.imread('image.jpg')

# 高度和宽度除以2得到图像的中心
height, width = image.shape[:2]
# 得到图像的中心坐标来创建2D旋转矩阵
center = (width/2, height/2)

# 使用 cv2.getRotationMatrix2D() 获取旋转矩阵
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=45, scale=1)

# 使用 cv2.warpAffine 旋转图像
rotated_image = cv2.warpAffine(src=image, M=rotate_matrix, dsize=(width, height))

cv2.imshow('Original image', image)
cv2.imshow('Rotated image', rotated_image)
# 等待直到按键盘上的任意键退出
cv2.waitKey(0)
# 将旋转后的图像保存到磁盘
cv2.imwrite('rotated_image.jpg', rotated_image)

(2)C++

#include 
#include
using namespace cv;

int main(int, char**) 
{
    Mat image = imread("image.jpg");
	  imshow("image", image);
	  waitKey(0);
	  double angle = 45;

	  // 高度和宽度除以2得到图像的中心
	  Point2f center((image.cols - 1) / 2.0, (image.rows - 1) / 2.0);
	  // 使用 getRotationMatrix2D() 获取旋转矩阵
	  Mat rotation_matix = getRotationMatrix2D(center, angle, 1.0);

	  // 我们将结果图像保存在rotated_image矩阵中
	  Mat rotated_image;
	  // 使用warpAffine旋转图像
	  warpAffine(image, rotated_image, rotation_matix, image.size());
	  imshow("Rotated image", rotated_image);
      // 等待直到按键盘上的任意键退出
	  waitKey(0);
	  // 将旋转后的图像保存到磁盘
	  imwrite("rotated_im.jpg", rotated_image);

	  return 0;
}

OpenCV基础(5)使用OpenCV进行图像旋转和平移_第1张图片

2.代码解析

  • 使用OpenCV进行图像旋转
    通过定义一个变换矩阵M,你可以将图像旋转一个特定的角度 θ \theta θ。这个矩阵通常是这样的:
    M = [ c o s θ − s i n θ s i n θ c o s θ ] M =\left[ \begin{matrix} cos\theta & -sin\theta\\ sin\theta & cos\theta\end{matrix} \right] M=[cosθsinθsinθcosθ]
    OpenCV提供了定义图像旋转中心的能力,并提供了缩放因子来调整图像的大小。在这种情况下,变换矩阵被修改为:
    M = [ α β ( 1 − α ) . c x − β . c y − β α β . c x + ( 1 − α ) . c y ] M =\left[ \begin{matrix} \alpha & \beta & (1-\alpha).c_x-\beta.c_y\\ -\beta & \alpha & \beta.c_x+(1-\alpha).c_y\end{matrix} \right] M=[αββα(1α).cxβ.cyβ.cx+(1α).cy]
    在上述矩阵中:
    α = s c a l e . c o s θ β = s c a l e . s i n θ \alpha=scale . cos\theta\\\beta=scale.sin\theta α=scale.cosθβ=scale.sinθ
    其中 c x c_x cx c y c_y cy是图像旋转的坐标。
    OpenCV提供了getRotationMatrix2D()函数来创建上面的转换矩阵。
    getRotationMatrix2D()函数接受以下参数:

    • center:输入图像的旋转中心
    • angle:以角度表示的旋转角度
    • scale:一个各向同性的比例因子来调整图像的大小。这可以是一个浮点值。例如,值1.0将保持输出图像与源图像的大小相同。值为2.0将使结果图像的大小是源图像的两倍。

    如果angle是正的,图像就会逆时针旋转。如果你想顺时针旋转图像相同的量,那么angle需要是负的。

    旋转是三步操作:

    • 首先,你需要找到旋转中心。这通常是你想要旋转的图像的中心。
    • 接下来,创建2D旋转矩阵。OpenCV提供了我们上面讨论过的getRotationMatrix2D()函数。
    • 最后,使用上一步创建的旋转矩阵,对图像应用仿射变换。OpenCV中的warpAffine()函数完成了这项工作。

    warpAffine()函数的作用是对图像应用仿射变换。在进行仿射变换后,原始图像中的所有平行线在输出图像中仍然保持平行。
    warpAffine()的完整语法如下:
    warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

    • src:原图
    • M:旋转矩阵
    • dsize:输出图像的尺寸
    • dst:输出图像
    • flags:如INTER_LINEARINTER_NEAREST插值方法的组合
    • borderMode:边界像素处理方法
    • borderValue:用于常量边界的值的默认值为0
  • 使用OpenCV实现图像平移
    在计算机视觉中,图像的平移是指沿着x轴和y轴移动指定数量的像素。设图像需要移动的像素为 t x t_x tx t y t_y ty,然后定义一个平移矩阵 M M M:
    M = [ 1 0 t x 0 1 t y ] M =\left[ \begin{matrix} 1 &0 &t_x\\ 0 & 1 & t_y\end{matrix} \right] M=[1001txty]
    现在,在按 t x t_x tx t y t_y ty值移动图像时,有几个点需要记住。

    • t x t_x tx提供正值将使图像向右移动,负值将使图像向左移动。
    • 类似地, t y t_y ty的正值将使图像向下移动,而负值将使图像向上移动。

    使用OpenCV,按照以下步骤平移图像:

    • 首先,读取图像并获得它的宽度和高度。
    • 接下来,就像旋转一样,创建一个变换矩阵,这是一个2D数组。这个矩阵包含了沿着x轴和y轴移动图像所需的信息。
    • 同样,在最后一步中,使用warpAffine()函数来应用仿射转换。

    (1)Python

    import cv2 
    import numpy as np
    
    # 读取图片
    image = cv2.imread('image.jpg')
    # 获取图像的宽度和高度
    height, width = image.shape[:2]
    # 获取tx和ty值
    # 您可以指定您所选择的任何值
    tx, ty = width / 4, height / 4
    
    # 使用tx和ty创建平移矩阵,它是一个NumPy数组
    translation_matrix = np.array([
        [1, 0, tx],
        [0, 1, ty]
    ], dtype=np.float32)
    # 对图像应用平移变换
    translated_image = cv2.warpAffine(src=image, M=translation_matrix, dsize=(width, height))
    # 显示原始和平移图像
    cv2.imshow('Translated image', translated_image)
    cv2.imshow('Original image', image)
    cv2.waitKey(0)
    # 将平移后的图像保存到磁盘
    cv2.imwrite('translated_image.jpg', translated_image)
    

    (2)C++

    #include "opencv2/opencv.hpp"
    using namespace cv
    // 读取图片
    Mat image = imread("image.jpg");
    // 获取图像的宽度和高度
    int height = image.cols;
    int width = image.rows;
    // 获取tx和ty值
    float tx = float(width) / 4;
    float ty = float(height) / 4;
    // 使用tx和ty创建平移矩阵
    float warp_values[] = { 1.0, 0.0, tx, 0.0, 1.0, ty };
    Mat translation_matrix = Mat(2, 3, CV_32F, warp_values);
    // 将生成的图像保存在translated_image矩阵中
    Mat translated_image;
    // 利用平移矩阵对原始图像进行仿射变换
    warpAffine(image, translated_image, translation_matrix, image.size());
    //显示原始和平移图像
    imshow("Translated image", translated_image);
    imshow("Original image", image);
    waitKey(0);
    // 将平移后的图像保存到磁盘
    imwrite("translated_image.jpg", translated_image);
    

OpenCV基础(5)使用OpenCV进行图像旋转和平移_第2张图片

3.有趣的应用

想要构建一个鸟瞰场景的应用程序吗?那么,获取一些关于OpenCV视角转换的信息。将它添加到您在这里已经学习的关于转换的所有内容中。然后去创建那个应用程序!

总结

在这篇文章中,你学习了使用OpenCV的图像旋转和平移操作。我们开始使用OpenCV旋转图像,我们使用getRotationMatrix2D()函数来获得一个2D旋转矩阵。然后我们将这个旋转矩阵传递给warpAffine()函数,以使图像围绕其中心点旋转所需的角度。

接下来,您学习了如何使用OpenCV平移图像。为此,我们明确定义了一个平移矩阵,它包含我们想要平移图像的x和y值。对于转换,我们还使用了warpAffine()函数来应用转换。

图像的旋转和平移是可以执行的最基本的几何变换之一,并将为学习使用OpenCV执行的其他变换提供一个很好的基础。我们鼓励您通过更改输入并查看结果来试验这些示例。

参考目录

https://learnopencv.com/image-rotation-and-translation-using-opencv/

你可能感兴趣的:(OpenCV,opencv,python,C++)