如今,图像编辑变得越来越受欢迎,因为手机拥有这种内置功能,可以让你对图像进行裁剪、旋转以及更多操作。
在这篇文章中,我们将探索和学习这些图像编辑技术。具体来说,我们将学习如何:
- 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 <iostream>
#include<opencv2/opencv.hpp>
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;
}
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_LINEAR
或INTER_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);
3.有趣的应用
想要构建一个鸟瞰场景的应用程序吗?那么,获取一些关于OpenCV视角转换的信息。将它添加到您在这里已经学习的关于转换的所有内容中。然后去创建那个应用程序!
总结
在这篇文章中,你学习了使用OpenCV的图像旋转和平移操作。我们开始使用OpenCV旋转图像,我们使用getRotationMatrix2D()
函数来获得一个2D旋转矩阵。然后我们将这个旋转矩阵传递给warpAffine()
函数,以使图像围绕其中心点旋转所需的角度。
接下来,您学习了如何使用OpenCV平移图像。为此,我们明确定义了一个平移矩阵,它包含我们想要平移图像的x和y值。对于转换,我们还使用了warpAffine()
函数来应用转换。
图像的旋转和平移是可以执行的最基本的几何变换之一,并将为学习使用OpenCV执行的其他变换提供一个很好的基础。我们鼓励您通过更改输入并查看结果来试验这些示例。
参考目录
https://learnopencv.com/image-rotation-and-translation-using-opencv/