1. 学习目标
- 学习 OpenCV 图像的翻转函数 cv.flip;
- 学习 NumPy 矩阵的反转函数 np.flip;
- 自己实现矩阵反转的函数。
2. OpenCV 翻转
翻转也称镜像,是指将图像沿轴线进行轴对称变换。水平镜像是将图像沿垂直中轴线进行左右翻转,垂直镜像是将图像沿水平中轴线进行上下翻转,水平垂直镜像是水平镜像和垂直镜像的叠加。
2.1 cv.flip() 函数说明
cv.flip(src, flipCode[, dst]) -> dst
2.2 参数说明
参数 | 说明 |
---|
src | 表示输入图像。 |
flipCode | 表示翻转轴线的控制参数,整型(int)。 |
dst | 表示变换操作的输出图像,可选项。 |
2.3 flipCode 值说明
值 | 说明 |
---|
0 | 表示水平翻转。 |
1 | 表示垂直翻转。 |
-1 | 表示对角线翻转。 |
3. 翻转实例
3.1 实例代码
import cv2 as cv
import numpy as np# 图像翻转
def image_flip():img = cv.imread("./images/lena.jpg")cv.imshow("original", img)# 水平翻转horizontally_img = cv.flip(img,0)cv.imshow("horizontally_img", horizontally_img)# 垂直翻转vertically_img = cv.flip(img,1)cv.imshow("vertically_img", vertically_img)# 对角线翻转horizontally_vertically_img = cv.flip(img,-1)cv.imshow("horizontally_vertically_img", horizontally_vertically_img)cv.waitKey(0)cv.destroyAllWindows()
if __name__ == "__main__":image_flip()
3.2 翻转效果

4. 矩阵反转
4.1 np.flip() 函数说明
numpy.flip(array, axis) → dst_array
4.2 参数说明
参数 | 说明 |
---|
array | 表示输入的数组。 |
axis | 表示[integer]轴,阵列沿此轴反转。 |
4.3 axis 值说明
5. 反转实例
5.1 实例代码
import cv2 as cv
import numpy as np# 阵列反转
def image_np_flip():img = cv.imread("./images/lena_small.jpg")cv.imshow("original", img)# 水平翻转horizontally_img = np.flip(img,0)cv.imshow("horizontally_img", horizontally_img)# 垂直翻转vertically_img = np.flip(img,1)cv.imshow("vertically_img", vertically_img)# 对角线翻转horizontally_vertically_img0 = np.flip(img,0)horizontally_vertically_img = np.flip(horizontally_vertically_img0,1)cv.imshow("horizontally_vertically_img", horizontally_vertically_img)cv.waitKey(0)cv.destroyAllWindows()
if __name__ == "__main__":image_np_flip()
5.2 反转效果

6. 实现阵列反转
6.1 实现阵列上下反转
- 获取阵列的宽高值;
- 复制一份改阵列,防止反转的时候影响了原阵列;
- 上下翻转只需要循环阵列的行,将第一行和最后一行互换,将第二行和倒数第二行互换!!!
- 注意:由于 range 是从 0 开始,所以最后一行需要先减 1!!!
- 注意:解构赋值直接将两个值进行互换,但是换的第一个值需要复制一份互换np.copy(src[i])!!!
# 上下翻转
def flip_ud(src):h,w,c = src.shapesrc = np.copy(src)for i in range(h//2):# cur = np.copy(src[i])# src[i] = src[h-i-1]# src[h-i-1] = cursrc[i],src[h-i-1] = src[h-i-1],np.copy(src[i])return src
6.2 实现阵列左右反转
- 对比上下反转,左右反转需要循环列一层的互换!!!
# 左右翻转
def flip_lr(src):h,w,c = src.shapesrc = np.copy(src)for i in range(h):for j in range(w//2):src[i][j],src[i][w-j-1] = src[i][w-j-1],np.copy(src[i][j])return src
6.3 实现阵列左上角和右下角反转
# 图像左上角和右下角翻转
def flip_lu_rd(src):h,w,c = src.shapesrc = np.copy(src)# 左上角和右下角翻转for i in range(h//2):for j in range(w//2):src[i][j],src[h-i-1][w-j-1] = src[h-i-1][w-j-1],np.copy(src[i][j])return src
6.4 使用 6.3 的方法实现对角线反转
- 图像左上角和右下角翻转;
- 右上角和左下角翻转;
2.1 左右翻转;
2.2 图像左上角和右下角翻转;
2.3 左右翻转图像还原。
def flip_ud_lr(src):# 图像左上角和右下角翻转src = flip_lu_rd(src)# 右上角和左下角翻转# 1. 左右翻转src = flip_lr(src)# 2. 图像左上角和右下角翻转src = flip_lu_rd(src)# 3. 左右翻转图像还原src = flip_lr(src)return src
6.5 直接使用 6.1 和 6.2 实现对角线反转
def flip_ud_lr(src):# 上下翻转src = flip_ud(src)# 左右翻转src = flip_lr(src)return src
7. 实现图像翻转实例
7.1 翻转实例代码
# 上下翻转
def flip_ud(src):h,w,c = src.shapesrc = np.copy(src)for i in range(h//2):# cur = np.copy(src[i])# src[i] = src[h-i-1]# src[h-i-1] = cursrc[i],src[h-i-1] = src[h-i-1],np.copy(src[i])return src# 左右翻转
def flip_lr(src):h,w,c = src.shapesrc = np.copy(src)for i in range(h):for j in range(w//2):src[i][j],src[i][w-j-1] = src[i][w-j-1],np.copy(src[i][j])return src# 图像左上角和右下角翻转
def flip_lu_rd(src):h,w,c = src.shapesrc = np.copy(src)# 左上角和右下角翻转for i in range(h//2):for j in range(w//2):src[i][j],src[h-i-1][w-j-1] = src[h-i-1][w-j-1],np.copy(src[i][j])return srcdef flip_ud_lr(src):# 图像左上角和右下角翻转src = flip_lu_rd(src)# 右上角和左下角翻转# 1. 左右翻转src = flip_lr(src)# 2. 图像左上角和右下角翻转src = flip_lu_rd(src)# 3. 左右翻转图像还原src = flip_lr(src)return srcdef image_self_flip():img = cv.imread("./images/lena_small.jpg")# cv.imshow("original", img)# 水平翻转horizontally_img = flip_ud(img)cv.imshow("horizontally_img", horizontally_img)# 垂直翻转vertically_img = flip_lr(img)cv.imshow("vertically_img", vertically_img)# 对角线翻转horizontally_vertically_img = flip_ud_lr(img)cv.imshow("horizontally_vertically_img", horizontally_vertically_img)cv.waitKey(0)cv.destroyAllWindows()if __name__ == "__main__":image_self_flip()
实现效果

8. 总结
- 注意: 阵列的反转 和 OpenCV 的翻转 对比,少了对角线翻转,但是使用【上下反转+左右反转】能够实现相同的效果;
- 自己使用循环阵列的方法实现水平、垂直、对角线翻转,但是相比原生方法,计算很慢,需要进行优化!!!