OpenCV学习笔记(9):图像的基本变换

OpenCV学习笔记(9):图像的基本变换

文章目录

  • OpenCV学习笔记(9):图像的基本变换
  • 01 图像的放大与缩小 cv2.resize()
  • 02 图像的翻转 cv2.flip()
  • 03 图像的旋转 cv2.rotate()
  • 04 仿射变换 cv2.warpAffine()
      • 仿射变换之图像平移操作
      • 仿射变换之获取变换矩阵API(1) cv2.getRotationMatrix2D()
      • 仿射变换之获取变换矩阵API(2) cv2.getAffineTransform()
      • 仿射变换之透视变换 cv2.warpPerspective()

01 图像的放大与缩小 cv2.resize()

# 01 图像的放大与缩小 cv2.resize()
# cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None) 超级实用的技能

先读图片

 	girl1 = cv2.imread('picture.png')
    girl2 = cv2.imread('picture_2.png')

	cv2.imshow('girl1', girl1)
    cv2.imshow('girl2', girl2)

    print(girl1.shape)  # (500, 500, 3)
    print(girl2.shape)  # (1387, 640, 3)

图片为:
OpenCV学习笔记(9):图像的基本变换_第1张图片

把girl2缩小成girl1大小,拼接后显示

	new_girl2 = cv2.resize(girl2, girl1.shape[0:2])
    cv2.imshow('resize girl2', np.hstack((girl1, new_girl2)))

或者再试一下把girl1放大成girl2,注意opencv内部读取图片是先读高,再读宽

	new_girl1 = cv2.resize(girl1, (400, 600))     # 这里注意 你写的话应该是先写宽的
    new_girl2 = cv2.resize(girl2, (500, 600))
    print(new_girl1.shape)  # ((600, 400, 3)
    cv2.imshow('resize girl1 and girl2', np.hstack((new_girl1, new_girl2)))   # 水平打包需要图像的高一致

下面确认参数interpolation的作用。默认为INTER_LINEAR

INTER_AREA:最好 #INTER_CUBIC (slow) or #INTER_LINEAR(faster but still looks OK).

	# INTER_AREA:最好 #INTER_CUBIC (slow) or #INTER_LINEAR(faster but still looks OK).
    newgirl1_1 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_NEAREST)
    newgirl1_2 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_LINEAR)  # 默认
    newgirl1_3 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_CUBIC)
    newgirl1_4 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_AREA)

    # 区别在nearest和area区别很大
    # cv2.imshow('nearest', newgirl1_1)
    # cv2.imshow('linear', newgirl1_1)
    # cv2.imshow('cubic', newgirl1_1)
    # cv2.imshow('area', newgirl1_1)

对比结果如下:

OpenCV学习笔记(9):图像的基本变换_第2张图片OpenCV学习笔记(9):图像的基本变换_第3张图片

OpenCV学习笔记(9):图像的基本变换_第4张图片OpenCV学习笔记(9):图像的基本变换_第5张图片

把图缩小了,看的结果不是很明显,记住上边结论就行。

还可以按照x, y轴的比例进行缩放

	new_girl2 = cv2.resize(girl2, dsize=None, fx=0.5, fy=0.5)
    print(new_girl2.shape)      # (694, 320, 3)
    # cv2.imshow('girl2', girl2)
    # cv2.imshow('resize girl2 fx fy', new_girl2)


由于屏幕大小的限制,图片不能完整显示,只需知道缩放了即可,缩放为原来图片的一半大小,x和y轴可以任意分别缩放。

完整代码为:

# 01 图像的放大与缩小
# cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None) 超级实用的技能
def resize_picture():
    girl1 = cv2.imread('picture.png')
    girl2 = cv2.imread('picture_2.png')
    # cv2.imshow('girl1', girl1)
    # cv2.imshow('girl2', girl2)

    print(girl1.shape)  # (500, 500, 3)
    print(girl2.shape)  # (1387, 640, 3)

    # 把girl2缩小成girl1大小
    new_girl2 = cv2.resize(girl2, girl1.shape[0:2])
    # cv2.imshow('resize girl2', np.hstack((girl1, new_girl2)))

    # 再试一下把girl1放大成girl2,注意opencv内部读取图片是先读高,再读宽
    new_girl1 = cv2.resize(girl1, (400, 600))     # 这里注意 你写的话应该是先写宽的
    new_girl2 = cv2.resize(girl2, (500, 600))
    print(new_girl1.shape)  # (600, 400, 3)
    # cv2.imshow('resize girl1 and girl2', np.hstack((new_girl1, new_girl2)))   # 水平打包需要图像的高一致

    # 对比interpolation 默认为INTER_LINEAR
    # INTER_AREA:最好 #INTER_CUBIC (slow) or #INTER_LINEAR(faster but still looks OK).
    newgirl1_1 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_NEAREST)
    newgirl1_2 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_LINEAR)  # 默认
    newgirl1_3 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_CUBIC)
    newgirl1_4 = cv2.resize(girl1, (650, 650), interpolation=cv2.INTER_AREA)

    # 在nearest和area区别大结果较明显
    # cv2.imshow('nearest', newgirl1_1)
    # cv2.imshow('linear', newgirl1_1)
    # cv2.imshow('cubic', newgirl1_1)
    # cv2.imshow('area', newgirl1_1)

    # 还可以按照x, y轴的比例进行缩放
    new_girl2 = cv2.resize(girl2, dsize=None, fx=0.5, fy=0.5)
    print(new_girl2.shape)      # (694, 320, 3)
    cv2.imshow('girl2', girl2)
    cv2.imshow('resize girl2 fx fy', new_girl2)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


resize_picture()

02 图像的翻转 cv2.flip()

重要参数:flipCode 等于0时为上下翻转,大于0时左右翻转,小于0时则为上下加左右翻转

# cv2.flip(src, flipCode[, dst])
# flipCode == 0上下翻转    flipCode > 0左右翻转    flipCode < 0 上下+左右

读取图片

girl = cv2.imread('picture.png')

上下翻转

new_girl = cv2.flip(girl, 0)  # 上下翻转
cv2.imshow('flip1', np.hstack((girl, new_girl)))

OpenCV学习笔记(9):图像的基本变换_第6张图片

左右翻转

new_girl2 = cv2.flip(girl, flipCode=1)  # 左右翻转
cv2.imshow('flip2', np.hstack((girl, new_girl2)))

OpenCV学习笔记(9):图像的基本变换_第7张图片

上下+左右

new_girl3 = cv2.flip(girl, flipCode=-1)  # 上下+左右
cv2.imshow('flip3', np.hstack((girl, new_girl3)))

OpenCV学习笔记(9):图像的基本变换_第8张图片

测试一下,-1或者-2没有影响的,都是上下+左右

new_girl4 = cv2.flip(girl, flipCode=-2)
cv2.imshow('flip4', np.hstack((girl, new_girl4)))

OpenCV学习笔记(9):图像的基本变换_第9张图片

再一个:利用numpy的知识

new_girl5 = girl[::-1, ::-1]
cv2.imshow('flip5', np.hstack((girl, new_girl5)))

结果和flip4一样,不再展示。

03 图像的旋转 cv2.rotate()

重要参数:rotateCode参数 ROTATE_90_CLOCKWISE 90度 ROTATE_180 180度 ROTATE_90_COUNTERCLOCKWISE 270度(逆时针90度)

# cv2.rotate(src, rotateCode, dst=None)
# rotateCode参数:ROTATE_90_CLOCKWISE 90度  ROTATE_180 180度 ROTATE_90_COUNTERCLOCKWISE 270度(逆时针90度)

不是很复杂,直接放在一块了

def rotate_picture():
    girl = cv2.imread('picture.png')
    # 把图片缩小一点,注意要是拼接的话,旋转以后高应该相等才行,否则会报错
    girl = cv2.resize(girl, (300, 300))

    new_girl1 = cv2.rotate(girl, rotateCode=cv2.ROTATE_90_CLOCKWISE)
    new_girl2 = cv2.rotate(girl, rotateCode=cv2.ROTATE_180)
    new_girl3 = cv2.rotate(girl, rotateCode=cv2.ROTATE_90_COUNTERCLOCKWISE)

    cv2.imshow('rotate', np.hstack((girl, new_girl1, new_girl2, new_girl3)))

    # 要是其他角度呢
    # new_girl4 = cv2.rotate(girl, rotateCode=60)   # 不行!!!会报错,opencv不支持这些任意角度,不灵性有没有 其实后边有
    # print(new_girl4.shape)
    # cv2.imshow('rotate:60', new_girl4)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


rotate_picture()

结果为:
OpenCV学习笔记(9):图像的基本变换_第10张图片

04 仿射变换 cv2.warpAffine()

仿射变换是图像旋转、缩放、平移的总称 具体做法是通过一个矩阵和原图片坐标进行计算,得到新的坐标完成变换,所以关键就是这个矩阵

# cv2.warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
# warp: 弯曲 affine: 仿射的
# M:变换矩阵(这是最重要的一个参数) dsize:输出图像大小 flag:与resize中的插值算法一致 mode:边界外推法标志 value:填充边界值

仿射变换之图像平移操作

girl = cv2.imread('picture.png')
h, w, ch = girl.shape

变换矩阵 最少是float32的,这里是通过直接手动计算变换矩阵M的,后边还有两种方式

M = np.float32([[1, 0, 200], [0, 1, 0]])
new_girl = cv2.warpAffine(girl, M, dsize=(w, h))

cv2.imshow('girl', girl)
cv2.imshow('new_girl', new_girl)

平移后结果为:
OpenCV学习笔记(9):图像的基本变换_第11张图片

仿射变换之获取变换矩阵API(1) cv2.getRotationMatrix2D()

简单的平移可以自己算M矩阵,那复杂一点的变换呢
opencv提供了计算变换矩阵的API cv2.getRotationMatrix2D()

通过中心点、旋转角度和缩放比例计算变换矩阵M

# cv2.getRotationMatrix2D(center, angle, scale)
# center: 中心点,旋转中心 angle:旋转角度(逆时针) scale:缩放比例

旋转位置(100, 100) 旋转角度15度 缩放比例 1

M = cv2.getRotationMatrix2D((100, 100), 15, 1)	
new_girl = cv2.warpAffine(girl, M, dsize=(w, h))

cv2.imshow('girl', girl)
cv2.imshow('new_girl', new_girl)


再试试按照中心位置转

M = cv2.getRotationMatrix2D((w / 2, h / 2), 30, 1)

仿射变换之获取变换矩阵API(2) cv2.getAffineTransform()

通过三点可以确定变换后的位置,相当于解方程,能解出偏移的参数和旋转的角度

# cv2.getAffineTransform(src, dst)
# src 原图的三个点 dst 旋转后的三个点

先计算M矩阵,再仿射变换

	src = np.float32([[200, 100], [300, 100], [200, 300]])
    dst = np.float32([[100, 150], [200, 100], [200, 200]])
    M = cv2.getAffineTransform(src, dst)

    new_girl = cv2.warpAffine(girl, M, dsize=(w, h))

    cv2.imshow('girl', girl)
    cv2.imshow('new_girl', new_girl)

OpenCV学习笔记(9):图像的基本变换_第12张图片

仿射变换之透视变换 cv2.warpPerspective()

透视变换就是将一种坐标系换成另一种坐标系。简单来说,可以把一张倾斜的图片变正

类似于手机自带的拍照文档模式一样

# cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

读取图片,这里新找了一张倾斜的网图
挺大的,先缩小

	img = cv2.imread('toushe.png')
    print(img.shape)    # (720, 960, 3)
    img = cv2.resize(img, (360, 480))

获取变换矩阵
getPerspectiveTransform(src, dst, solveMethod=None)

	# 获取变换矩阵
    # getPerspectiveTransform(src, dst, solveMethod=None)
    # src:原图的4个坐标
    src = np.float32([[0, 0], [900, 80], [0, 720], [900, 680]])
    dst = np.float32([[0, 0], [1000, 0], [0, 720], [1000, 720]])
    M = cv2.getPerspectiveTransform(src, dst)

    new_img = cv2.warpPerspective(img, M, (360, 480))

    cv2.imshow('img', img)
    cv2.imshow('new_img', new_img)

多次调整,结果为:
OpenCV学习笔记(9):图像的基本变换_第13张图片

觉得有用的小伙伴点个赞加个关注支持一下吧!有错误或者不恰当的地方请指出!一起学习、进步!!!

你可能感兴趣的:(OpenCV,opencv,学习,python,图像处理,计算机视觉)