跳转至

图像翻转

概要

本节讲解了用OpenCV的flip函数, numpy的索引,以及wrapAffine 三种方式实现图像翻转.

keywords : flip 图像翻转 水平翻转 镜像 垂直翻转

使用flip函数实现翻转

flip 函数原型

flip(src, flipCode[, dst]) -> dst

参数解析

  • src 输入图片

  • flipCode 翻转代码

  • 1 水平翻转 Horizontally (图片第二维度是column)

  • 0 垂直翻转 *Vertically * (图片第一维是row)

  • -1 同时水平翻转与垂直反转 Horizontally & Vertically

为了方便使用, 你也可以封装成下面的函数

def flip(image, direction):
    if direction == "h":
        flipped = cv2.flip(image, 1)
    elif direction == "v":
        flipped = cv2.flip(image, 0)
    else:
        # both horizontally and vertically
        flipped = cv2.flip(image, -1)

201802191033

src/flip_demo.py

'''
反转Demo
'''
import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('cat.png')

def bgr2rbg(img):
    '''
        将颜色空间从BGR转换为RBG
    '''
    return img[:,:,::-1]

# 水平翻转
flip_h = cv2.flip(img, 1)
# 垂直翻转
flip_v = cv2.flip(img, 0)
# 同时水平翻转与垂直翻转
flip_hv = cv2.flip(img, -1)

plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img))

plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h))

plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v))

plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv))

plt.show()

利用numpy的索引实现翻转

利用numpy中ndarray的索引, 我们可以非常方便地实现图像翻转。

# 水平翻转
flip_h =  img[:,::-1]
# 垂直翻转
flip_v =  img[::-1]
# 水平垂直同时翻转
flip_hv =  img[::-1, ::-1]

201802191033

'''
使用numpy的索引进行图像反转
'''
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('cat.png')
height,width,channel = img.shape

# 水平翻转
flip_h =  img[:,::-1]

# 垂直翻转
flip_v =  img[::-1]

# 水平垂直同时翻转
flip_hv =  img[::-1, ::-1]

def bgr2rbg(img):
    '''
        将颜色空间从BGR转换为RBG
    '''
    return img[:,:,::-1]

plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img))

plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h))

plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v))

plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv))

plt.show()

!!学霸分割线!!
如果你对图像翻转的数学原理不感兴趣的话,就不需要往下看了.


利用wrapAffine实现翻转

注: width 代表图像的宽度 height代表图像的高度

水平翻转的变换矩阵

\begin{equation} { \left[ \begin{array}{c} x'\\ y'\\ \end{array} \right ]}= { \left[ \begin{array}{cc} -1 & 0\\ 0 & 1\\ \end{array} \right ]}\times { \left[\begin{array}{c} x\\ y\\ \end{array} \right] }+ { \left[\begin{array}{c} width\\ 0 \\ \end{array} \right] } \end{equation}
M = { \left[ \begin{array}{ccdc} -1 & 0 & width\\ 0 & 1 & 0\\ \end{array} \right ]}

垂直翻转的变换矩阵

\begin{equation} { \left[ \begin{array}{c} x'\\ y'\\ \end{array} \right ]}= { \left[ \begin{array}{cc} 1 & 0\\ 0 & -1\\ \end{array} \right ]}\times { \left[\begin{array}{c} x\\ y\\ \end{array} \right] }+ { \left[\begin{array}{c} 0\\ height \\ \end{array} \right] } \end{equation}
M = { \left[ \begin{array}{ccc} 1 & 0 & 0\\ 0 & -1 & height\\ \end{array} \right ]}

同时进行水平翻转与垂直翻转

\begin{equation} { \left[ \begin{array}{c} x'\\ y'\\ \end{array} \right ]}= { \left[ \begin{array}{cc} -1 & 0\\ 0 & -1\\ \end{array} \right ]}\times { \left[\begin{array}{c} x\\ y\\ \end{array} \right] }+ { \left[\begin{array}{c} width\\ height \\ \end{array} \right] } \end{equation}
M = { \left[ \begin{array}{ccc} -1 & 0 & width\\ 0 & -1 & height\\ \end{array} \right ]}

201802191033

src/flip_by_warpaffine.py

'''
使用仿射矩阵实现反转
'''
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('cat.png')
height,width,channel = img.shape

# 水平翻转
M1 = np.float32([[-1, 0, width], [0, 1, 0]])
flip_h =  cv2.warpAffine(img, M1, (width, height))

# 垂直翻转
M2 = np.float32([[1, 0, 0], [0, -1, height]])
flip_v =  cv2.warpAffine(img, M2, (width, height))

# 水平垂直同时翻转
M3 = np.float32([[-1, 0, width], [0, -1, height]])
flip_hv =  cv2.warpAffine(img, M3, (width, height))

def bgr2rbg(img):
    '''
        将颜色空间从BGR转换为RBG
    '''
    return img[:,:,::-1]

plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img))

plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h))

plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v))

plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv))

plt.show()