- 1.图像变换–仿射和非仿射变换
- 2.图像转换–上下左右移动图像
- 3.图像旋转–旋转图像
- 4.缩放,调整大小和内插
- 5.图像金字塔–调整大小的另一种方法
- 6.裁剪–裁剪所需的图像区域
- 7.用于使图像变亮和变暗的算术运算
在上一教程中,我们了解了OpenCV,并使用它进行了一些基本的图像处理,例如灰度缩放,色彩饱和度,直方图,色彩空间,RGB分量等。如上一教程所述,OpenCV是开源通勤者视觉库, C ++,Python和Java接口,并支持Windows,Linux,Mac OS,iOS和Android。因此,可以在具有Python和Linux环境的Raspberry Pi中轻松安装它。带有OpenCV和附加摄像头的Raspberry Pi可用于创建许多实时图像处理应用程序,例如人脸检测,人脸锁,物体跟踪,汽车车牌检测,家庭安全系统等。
在本教程中,我们将看到如何使用OpenCV来操纵图像。在这里,我们将学习使用OpenCV在图像上应用以下功能:
- 图像变换–仿射和非仿射变换
- 图像翻译–上下左右移动图像
- 图像旋转–旋转图像
- 缩放,调整大小和插值
- 图像金字塔–调整大小的另一种方法
- 裁剪–裁剪所需的图像区域
- 使图像变亮和变暗的算术运算
1.图像变换–仿射和非仿射变换
变换是作用在图像上的几何变形,变形在这里当然不是指错误,而是一种校正类型,用于校正从捕获图像的点产生的透视问题。图像转换有两种类型-仿射和非仿射
仿射变换具有缩放,旋转和平移三种类型,仿射变换的重要之处在于图像变换之前和之后的线是平行的。
非仿射变换或射影变换不会保留平行度,长度或角度,但是会保留共线性和入射角,共线性意味着两个点位于同一条直线上。
非仿射变换在计算机视觉中非常普遍,并且是从不同的摄影机角度生成的。非仿射或投影变换也称为单应性。
2.图像转换–上下左右移动图像
如果我们同时执行x和y转换,则图像转换将使图像上下左右移动,甚至对角线移动。
现在,为了执行图像翻译,我们使用opencv的warpAffine函数,使用 cv2.warpAffine 实现这些翻译,但是为此,我们需要一个翻译矩阵。
翻译矩阵,
T = 1 0 Tx
0 1 ty
T X,T y是发生图像偏移的方向。
其中,T X沿X轴移动(水平)
T Y沿Y轴移动(垂直)
#这是一个仿射变换,仅改变图像的位置 #我们使用cv2.warpAffine来实现这些变换。 import cv2 import numpy as np image = cv2.imread('input.jpg') #存储图像的高度和宽度 height,width = image.shape print(image.shape) quater_height,quater_width = height / 4,width / 4 T = np.float32(,]) img_translation = cv2.warpAffine(image,T,(width,height)) print(T) cv2.imshow('original_image',image) cv2.waitKey(0) cv2.imshow('翻译',img_translation) cv2.waitKey(0) cv2.destroyAllWindows()
控制台输出-(183,275)–高度和宽度
-T矩阵
]
3.图像旋转–旋转图像
图像旋转是围绕一个点或图像中心的一个点旋转图像,就像旋转点的作用就像枢轴一样。
在翻译中,我们有T矩阵,在旋转中,我们有M矩阵
旋转矩阵,M矩阵=Cosθ-Sinθ
正弦余弦
θ是旋转角度,沿逆时针方向测量。
还有一点需要注意的是,OpenCV允许您使用功能 cv2.getRotationMatrix2D(rotation_center_x,rotation_center_y,旋转角度,比例) 同时出售和旋转图像
我们仍然使用opencv的warpAffine函数来获取图像的旋转,但不是像以前的情况那样使用平移矩阵来代替平移矩阵。
import cv2 import numpy as np image = cv2.imread('input.jpg') height,width = image.shape #将高度和宽度除以2以围绕其中心 旋转 图像rotation_matrix = cv2.getRotationMatrix2D((width / 2 ,height / 2),90,1)rotation_image = cv2.warpAffine(image,rotation_matrix,(width,height)) cv2.imshow('原始图像',图像) cv2.waitKey(0) cv2.imshow('旋转图像', rotated_image )cv2.waitKey(0)cv2.destroyAllWindows()
现在将图像旋转90度,由于画布大小而将其裁剪,因为画布大小保持不变,但由于旋转,图像大小无法适应画布大小。可以通过将缩放因子设置为负数来进行调整,但是它允许图像后面出现黑色背景。
因此,可以通过预测图像或猜测图像来设置图像的高度和宽度,或者通过移调图像来旋转图像,但是这会使图像沿逆时针方向旋转90度的倍数。
4.缩放,调整大小和内插
缩放和调整大小是仿射变换,调整图像的大小是我们已经做的相当长的时间,并且我们还处理了插值,例如当您将图像调整为更大的尺寸时,例如我们正在扩展像素时,像素,这就是插值的目的。
图像大小从较小变大或从较大变小可能会发生这种情况。
从技术上讲,插值是在离散的一组已知数据点内构造新数据点(像素)的方法。
OpenCV中有多种插值方法,例如
cv2.INTER_AREA –适用于缩小或缩小采样
cv2.INTER_NEAREST-最快
cv2.LINEAR –适用于放大或放大采样(默认)
cv2.CUBIC-更好
cv2.INTER_LANCZOS4-最佳
#使用cv2.resize函数调整大小非常容易,其参数为 #cv2.resize(image,dsize(输出图像大小),x_scale,y_scale,插值) import cv2 import numpy as np image = cv2.imread('input。 jpg') cv2.imshow('Original_image',image) cv2.waitKey(0) #让 图像变为原始图像大小的3/4,即缩小到75%image_scaled = cv2.resize(image,None,fx = 0.75,fy = 0.75) #因为线性插值是open cv的默认方法,所以我们不需要将其实现为函数。 cv2.imshow('缩放线性插值',image_scaled) cv2.waitKey(0) #让图像尺寸 翻倍img_double = cv2.resize(image,None,fx = 2,fy = 2,interpolation = cv2.INTER_CUBIC) cv2.imshow('scaing_cubicInterpolation',img_double) cv2.waitKey(0) #让我们通过精确尺寸进行大小调整 image_resize = cv2.resize(image,(200,300),interpolation = cv2.INTER_AREA) cv2.imshow('scaling_exact', image_resize) cv2.waitKey(0) cv2.destroyAllWindows()
5.图像金字塔–调整大小的另一种方法
金字塔图像是指放大(放大图像)或缩小(缩小图像)。
这只是一种不同的调整大小方式,它使我们能够轻松快速地缩放图像,缩小后将新图像的高度和宽度减小一半。
当使物体检测器在每次寻找物体时缩放图像时,这很有用。
导入cv2 image = cv2.imread('input.jpg') 较小= cv2.pyrDown(图像) 较大= cv2.pyrUp(较小) cv2.imshow('原始',图像) cv2.waitKey(0) cv2.imshow( '较小',较小) cv2.waitKey(0) cv2.imshow('较大',较大) cv2.waitKey(0) cv2.destroyAllWindows()
在较大的图像中,您会注意到仍然与原始图像具有相同的大小,几乎没有模糊,因为它是直接从较小的图像转换为较大的图像的。但是,如果我们对其进行插值,则图像质量会比上一个图像有所改善,因为插值在放大图像时会在填充空间的同时估计像素。
现在运行相同的代码,但使用三次插值可以提供更好的大图像质量。下面的图像显示了原始图像,图像的放大版本,较小的图像和较小图像的三次插值版本之间的比较。
导入cv2 image = cv2.imread('input.jpg') 较小= cv2.pyrDown(图像) 较大= cv2.pyrUp(较小) cv2.imshow('原始',图像) cv2.waitKey(0) cv2.imshow( '较小',较小) cv2.waitKey(0) cv2.imshow('较大',较大) cv2.waitKey(0) #使用三次插值来 提高 从较小图像转换后的较大图像的质量img_double = cv2.resize(较小,无,fx = 2,fy = 2,插值= cv2.INTER_CUBIC)cv2.imshow('scaing_cubicInterpolation',img_double) cv2.waitKey(0) cv2.destroyAllWindows()
注意: 如果要创建尺寸越来越小的图像小副本或尺寸不断增长的图像大副本,那么我们可以使用 for 循环或 while 循环保持在 pyrDown 或 pyrUp 函数内部。
6.裁剪–裁剪所需的图像区域
裁剪图像是指提取图像片段。
OpenCV直接不具有裁剪功能,但是可以使用以下代码通过 numpy 轻松完成
裁剪=图像
我们将图像数组放置在numpy中,并使用索引工具或方法,在开始行到结束行之间定义开始行,在开始列到结束列之间定义一个逗号,该逗号提取要裁剪的矩形以获得图像。
import cv2 import numpy as np image = cv2.imread('input.jpg') height,width = image.shape #让我们获取起始像素坐标(裁剪矩形的左上角) start_row,start_col = int(height *.25) ,int(width *.25) #让我们获得结束像素坐标(右下) end_row,end_col = int(height *.75),int(width *.75) #简单地使用索引来裁剪出我们想要 裁剪 的矩形=图像cv2.imshow(“原始图像”,图像) cv2.waitKey(0) cv2.imshow(“裁剪图像”,已裁剪) cv2.waitKey(0) cv2.destroyAllWindows()
请注意, 您可以直接使用像素值来代替 start_col 或 start_row ,它们只是为了方便用户识别而给出。
7.用于使图像变亮和变暗的算术运算
OpenCV中的算术运算基本上是在图像上增加或减少矩阵,增加或减少矩阵会影响亮度的增加或减少。
因此,要添加或减去矩阵,我们必须创建它们,并且numpy具有一个称为 np.ones 的函数,该函数提供与图像大小相同的1的矩阵。
import cv2 import numpy as np image = cv2.imread('input.jpg') #创建一个矩阵,然后乘以100'的缩放器 #np.ones给出一个矩阵,其维数与图像大小相同在这种情况下,值为100 M = np.ones(image.shape,dtype =“ uint8”)* 100 #我们使用此值将此矩阵M添加到我们的图像中 #注意增加的亮度 = cv2.add(image ,M) cv2.imshow(“已添加”,已添加) cv2.waitKey(0) #同样,我们也可以减去 #注意亮度降低量 减去= cv2.subtract(image,M) cv2.imshow(“减去”,减去) cv2.waitKey(0) cv2.destroyAllWindows()
这就是OpenCV可用于在图像上应用许多不同图像处理操作的方式。在下一个教程中,我们将继续其他图像处理功能。