声明:本文只用于个人总结及学习使用,如有侵权,请留言,会尽快删除对应内容。
目录
一、平移
首先利用numpy构建一个平移矩阵,该矩阵的size为2×3。第一行第三列的数值即为横向平移的数值,第二行第三列的数值即为纵向平移的数值。图像的坐标系是以图像最左上角的点为原点建立的,数值为负值即为向左或向上平移的距离。
例如,我们要将图像向左平移100像素,向上平移10像素,那么我们的 M[0][2] 和 M[1][2]就都应为负值
def translation(img):
M = np.array([[1, 0, -100], [0, 1, -10]], dtype=np.float32)
img_change = cv2.warpAffine(img, M, (500, 500))
# zh_ch()是我自己写的一个处理中文乱码的函数
cv2.imshow(zh_ch("fruit_bike 平移"), img_change) # 其实不建议使用中文,容易出现乱码
cv2.waitKey(0)
利用cv2.warpAffine()函数来完成平移操作。cv2.warpAffine中的参数说明如下:
src - 输入图像。
M - 变换矩阵 2×3。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - 边界填充值; 默认情况下,它为0
平移后的效果如图所示:
二、镜像
镜像涉及到三个方向,即水平镜像、垂直镜像和水平垂直镜像,利用cv2.flip(src, flipCode, dst)实现,其中flipCode代表上述三个方向的代码,
src – 输入的图像
dst – 输出的图像
flipCode – 翻转模式:
① flipCode == 0垂直翻转(沿X轴翻转);
② flipCode > 0水平翻转(沿Y轴翻转);
③ flipCode < 0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
如下代码:
def mirroring(img):
# 水平镜像
h_flip = cv2.flip(img, 1)
cv2.imshow("fruit_bike horizontally", h_flip)
cv2.waitKey(0)
# 垂直镜像
v_flip = cv2.flip(img, 0)
cv2.imshow("fruit_bike vertically", v_flip)
cv2.waitKey(0)
# 水平垂直镜像
hv_flip = cv2.flip(img, -1)
cv2.imshow("fruit_bike horizontally-vertically", hv_flip)
cv2.waitKey(0)
原图及其结果如图所示(左上为原图,右上为水平镜像,左下为垂直镜像,右下为水平垂直镜像):
三、缩放
利用cv2.resize(src, dsize, dst=None, fx=None,fy=None,interpolation=None)方法进行缩放,其中fx和fy都为整型,表示要缩放后的大小。假设原图尺寸为100×100,要缩小为原图的一半大小,那么fx=50,fy=50。
src - 原图
dsize - 输出图像尺寸
fx - 沿水平轴的比例因子 (int)
fy - 沿垂直轴的比例因子 (int)
interpolation - 插值方法
如下代码:
def resize(img):
height, width = img.shape[:2] # 取宽和高
res = cv2.resize(img, (2 * width, 2 * height)) # 放大2倍
cv2.imshow("fruit_bike - large", res)
cv2.waitKey(0)
# 缩小为原来的一半
res = cv2.resize(img, (int(width / 2), int(height / 2)), interpolation=cv2.INTER_CUBIC)
cv2.imshow("fruit_bike - small", res)
cv2.waitKey(0)
原图
放大为原来的2倍
缩小为原来的一半
四、旋转
旋转就是对图像中的每个点的两个坐标值乘一个旋转矩阵
OpenCV 中对图像的旋转主要是先通过getRotationMatrix2D函数得到图像的旋转矩阵,然后再通过仿射变换函数warpAffine得到旋转后的图像。
其中cv2.getRotationMatrix2D(center, angle, scale)的参数说明如下
center - 表示旋转的中心点
angle - 表示旋转的角度degrees(正角度为逆时针,如angle=90,则会逆时针旋转90°)
scale - 图像缩放因子
cv2.warpAffine(src, M, dsize,dst=None,flags=None,borderMode=None,borderValue=None)函数的参数:
src - 输入的图像
M - 2 X 3 的变换矩阵.
dsize - 输出的图像的size大小
dst - 输出的图像flags - 输出图像的插值方法
borderMode - 图像边界的处理方式
borderValue - 当图像边界处理方式为 BORDER_CONSTANT 时的填充值
如下代码:
def rotation(img):
height, width = img.shape[:2]
# 旋转90°
M = cv2.getRotationMatrix2D((width / 2, height / 2), 90, 1) # 围绕中心点进行旋转
img_change = cv2.warpAffine(img, M, (width, height))
cv2.imshow("90", img_change)
cv2.waitKey(0)
M = cv2.getRotationMatrix2D((width / 2, height / 2), -45, 1)
img_change = cv2.warpAffine(img, M, (width, height))
cv2.imshow("-45", img_change)
cv2.waitKey(0)
图像输出两组,一个是逆时针旋转90°,一个是顺时针旋转45°
原图 ↑ 逆时针旋转90° ↓
顺时针旋转45° ↓
五、仿射
参考知乎大神的解释:如何通俗地讲解「仿射变换」这个概念?
下面通过一个动画来演示仿射操作:
对图像进行变换(三点得到一个变换矩阵),我们知道三点确定一个平面,我们也可以通过确定三个点的关系来得到转换矩阵,然后再通过warpAffine来进行变换。
通过GetAffineTransform 来得到变换矩阵M。
cv2.GetAffineTransform(src, dst) 中的参数为变换前后的三个点的坐标:
src - 原始图像中的三个点的坐标
dst - 变换后的这三个点对应的坐标
如下代码:
def affine(img):
height, width = img.shape[:2]
point1 = np.float32([[50, 50], [300, 50], [50, 200]])
point2 = np.float32([[10, 100], [300, 50], [100, 250]])
M = cv2.getAffineTransform(point1, point2)
dst = cv2.warpAffine(img, M, (width, height), borderValue=(255, 255, 255))
cv2.imshow("affine", dst)
cv2.waitKey(0)
运行结果如图所示(左图为原图,右图为处理后的图像):
六、灰度化
真彩色图像又称为RGB图像,RGB分别代表由红、绿、蓝三种颜色,通过这三种颜色并按照不同的比例则可以合成出不同的颜色,所以RGB也称为三基色。在RGB模型中,若其值R=G=B,则表示的是一种灰度颜色,只有强度信息,而没有颜色信息,对应的R=G=B时的值称为灰度值,用gray表示,图像的转化过程则称为灰度化处理。
(1)最大值法:将彩色图像中的三分量亮度的最大值作为灰度图的灰度值,即
(2)平均值法:将彩色图像中的三分量亮度求平均得到一个灰度图,即
(3)加权平均值法:根据重要性及其它指标,将三个分量以不同的权值进行加权平均。即
常用的彩色图像到灰度图像的转换公式为:
通过cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)进行灰度化处理。
如下代码:
def graying(img):
dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("graying", dst)
cv2.waitKey(0)
进行灰度化处理(左图为原图,右图为处理后的图像):
七、锐化
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
dst=cv2.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
其中cv2.filter2D的参数说明如下:
src - 原图像
dst - 目标
ddepth - 目标图像的所需深度,当ddepth=-1时,表示输出图像与原图像有相同的深度。
kernel - 卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用拆分将图像拆分为单独的颜色平面,然后单独处理它们。
anchor - 内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1)表示锚位于内核中心。
detal - 在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置。
borderType - 像素外推法,参见BorderTypes
如下代码:
def sharpen(image):
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) # 锐化
dst = cv2.filter2D(image, -1, kernel=kernel) # Note:当ddepth=-1时,表示输出图像与原图像有相同的深度。
cv2.imshow("sharpen", dst)
cv2.waitKey(0)
输出结果(左图为原图,右图为处理后的图像):
八、填充
即在图像上下左右四个方向上进行像素填充。
cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(0, 0, 0))
top, bottom, left, right表示:四个方向上填充的宽度
value=(0, 0, 0))表示填充的颜色,其排列不是RGB,而是BGR。
如下代码:
def padding(img):
dst = cv2.copyMakeBorder(img, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value=(0, 0, 255)) # top bottom left right;(BGR)
cv2.imshow("padding", dst)
cv2.waitKey(0)
输出结果(左图为原图,右图为处理后的图像):
使用PIL进行亮度增强 色度增强 对比度增强 锐度增强 模糊处理
原图:
增强亮度
# 增加亮度
def highlight(img):
t_img = img
enh_bri = ImageEnhance.Brightness(t_img)
brightness = 1.5
image_brightened = enh_bri.enhance(brightness)
image_brightened.show()
增强色度
# 增强色度
def enhance_chromaticity(img):
t_img = img
enh_col = ImageEnhance.Color(t_img)
color = 1.5
image_colored = enh_col.enhance(color)
image_colored.show()
增强对比度
# 增强对比度
def enhancing_contrast_ratio(img):
t_img = img
enh_con = ImageEnhance.Contrast(t_img)
contrast = 1.5
image_contrasted = enh_con.enhance(contrast)
image_contrasted.show()
增强锐度
# 增强锐度
def enhance_acutance(img):
t_img = img
enh_sha = ImageEnhance.Sharpness(t_img)
sharpness = 3.0
image_sharped = enh_sha.enhance(sharpness)
image_sharped.show()
模糊处理
高斯模糊,可以理解为每一个像素都取周边像素的平均值。
# 模糊
def darken_func(img):
t_img = img
t_img = t_img.filter(ImageFilter.GaussianBlur) # 高斯模糊
t_img.show()
参考文章:
Opencv常用数据增强方法:平移+旋转+缩放+模糊+光强+拉伸
基于OpenCV做图像数据增强(平移、镜像、缩放、旋转、仿射)