Opencv-Python学习笔记五——图像翻转,平移,仿射及透视 warpAffine

本篇笔记主要记录Opencv里的图像翻转,平移,旋转,仿射及透视功能,主要是下面几个API:

  • cv2.flip() # 图像翻转
  • cv2.warpAffine() #图像仿射
  • cv2.getRotationMatrix2D() #取得旋转角度的Matrix
  • cv2.GetAffineTransform(src, dst, mapMatrix) #取得图像仿射的matrix
  • cv2.getPerspectiveTransform(src, dst) #取得图像透视的4个点起止值
  • cv2.warpPerspective() #图像透视

图像翻转 cv2.flip()

cv2.flip(src, flipCode[, dst]) → dst

  • src: 原始图像矩阵;
  • dst: 变换后的矩阵;
  • flipMode: 翻转模式,有三种模式
    • 0 --- 垂直方向翻转; 1----- 水平方向翻转; -1:水平、垂直方向同时翻转

    flipCode==0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)

%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np
import cv2

image = cv2.imread("aier.jpg")
# Flipped Horizontally 水平翻转
h_flip = cv2.flip(image, 1)
# Flipped Vertically 垂直翻转
v_flip = cv2.flip(image, 0)
# Flipped Horizontally & Vertically 水平垂直翻转
hv_flip = cv2.flip(image, -1)

plt.figure(figsize=(8,8))

plt.subplot(221)
plt.imshow(image[:,:,::-1])
plt.title('original')

plt.subplot(222)
plt.imshow(h_flip[:,:,::-1])
plt.title('horizontal flip')

plt.subplot(223)
plt.imshow(v_flip[:,:,::-1])
plt.title(' vertical flip')

plt.subplot(224)
plt.imshow(hv_flip[:,:,::-1])
plt.title('h_v flip')
# 调整子图间距
# plt.subplots_adjust(wspace=0.5, hspace=0.1)
plt.subplots_adjust(top=0.8, bottom=0.08, left=0.10, right=0.95, hspace=0,
                    wspace=0.35)
# plt.tight_layout()
plt.show()
cv2.flip()

图像平移,旋转,仿射  cv2.warpAffine()

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

src input image.
dst output image that has the size dsize and the same type as src .
M   2×3 transformation matrix.
dsize   size of the output image.
flags   combination of interpolation methods (see InterpolationFlags) and the optional flag WARP_INVERSE_MAP that means that M is the inverse transformation ( dst→src ).
borderMode  pixel extrapolation method (see BorderTypes); when borderMode=BORDER_TRANSPARENT, it means that the pixels in the destination image corresponding to the "outliers" in the source image are not modified by the function.
borderValue value used in case of a constant border; by default, it is 0.

cv2.getRotationMatrix2D(center, angle, scale)

函数有三个参数:

  • center:图片的旋转中心
  • angle:旋转角度
  • scale:缩放比例,该例中0.5表示我们缩小一半
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as np

img = cv2.imread('aier.jpg')
rows,cols = img.shape[:2]

# 定义平移矩阵,需要是numpy的float32类型
# x轴平移200,y轴平移100, 2*3矩阵
M = np.float32([[1, 0, 200], [0, 1, 100]])
# 用仿射变换实现平移
img_s = cv2.warpAffine(img, M, (cols, rows), borderValue=(155, 150, 200))

# 第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例, 生成一2*3的矩阵
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
M1 = cv2.getRotationMatrix2D((cols/2,rows/2),180,1)
M2 = cv2.getRotationMatrix2D((cols/2,rows/2),60,1)
print(M)
'''
[[ 6.123234e-17  1.000000e+00  1.500000e+02]
 [-1.000000e+00  6.123234e-17  6.500000e+02]]
'''
# 第三个参数:变换后的图像大小
img_tra = cv2.warpAffine(img,M,(cols,rows))
img_tra1 = cv2.warpAffine(img,M1,(cols,rows))
img_tra2 = cv2.warpAffine(img,M2,(cols,rows), borderValue=(155, 100, 155))

plt.figure(figsize=(8,8))
plt.subplot(221)
plt.imshow(img[:,:,::-1])

plt.subplot(222)
plt.imshow(img_s[:,:,::-1])

plt.subplot(223)
plt.imshow(img_tra[:,:,::-1])

plt.subplot(224)
plt.imshow(img_tra2[:,:,::-1])

plt.subplots_adjust(top=0.8, bottom=0.08, left=0.10, right=0.95, hspace=0,
                    wspace=0.35)
plt.show()
平移,旋转

图像仿射

图像的旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,opencv提供了根据变换前后三个点的对应关系来自动求解M。这个函数是
M=cv2.getAffineTransform(pos1,pos2),其中两个位置就是变换前后的对应位置关系。输出的就是仿射矩阵M。然后在使用函数cv2.warpAffine()。

cv.GetAffineTransform(src, dst, mapMatrix) → None

  • Parameters: 变换前的三个点与其对应的变换后的点.
    • src – Coordinates of triangle vertices in the source image.
    • dst – Coordinates of the corresponding triangle vertices in the destination image.

The function calculates the 2*3 matrix of an affine transform.

AffineMatrix = cv2.getAffineTransform(np.array(SrcPointsA),
np.array(CanvasPointsA))

图像仿射示例图
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as np

img = cv2.imread('aier.jpg')
rows,cols = img.shape[:2]
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,20],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
#第三个参数:变换后的图像大小
res = cv2.warpAffine(img,M,(rows,cols))
plt.subplot(121)
plt.imshow(img[:,:,::-1])

plt.subplot(122)
plt.imshow(res[:,:,::-1])

plt.show()

透视 Perspective

视角变换,需要一个3*3变换矩阵。在变换前后要保证直线还是直线。
构建此矩阵需要在输入图像中找寻 4个点,以及在输出图像中对应的位置。这四个点中的任意三个点不能共线。

## pts1 ==> pts2
pts1=np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2=np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)

cv2.getPerspectiveTransform(np.array(SrcPointsA), np.array(CanvasPointsA))

cv2.getPerspectiveTransform(src, dst) → retval

cv2.warpPerspective(Img, PerspectiveMatrix, (300, 300))

cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst

src – input image.
dst – output image that has the size dsize and the same type as src .
M – 3*3 transformation matrix.
dsize – size of the output image.
flags – combination of interpolation methods (INTER_LINEAR or INTER_NEAREST) and the optional flag WARP_INVERSE_MAP, that sets M as the inverse transformation ( dst ---> src ).
borderMode – pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).
borderValue – value used in case of a constant border; by default, it equals 0.
4个点前后映射示例图
%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as np

img=cv2.imread('aier.jpg')
rows,cols,ch=img.shape
pts1=np.float32([[56,5],[368,5],[28,387],[389,390]])
pts2=np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)
print(M)
dst=cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
图像透视

本文主要内容就是这些,其他更深入功能待后续继续完善.....
[参考]
Geometric Transformations of Images

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容