openCV-python(三)图像的几何变换-仿射变换

openCV函数介绍

OpenCV提供了两个转换函数cv.warpAffine和cv.warpPerspective,您可以使用它们进行各种转换。cv.warpAffine采用2x3转换矩阵(即仿射变换),而cv.warpPerspective采用3x3转换矩阵(即透视变换)作为输入。这里介绍仿射变换的操作。
了解放射变换和透射变换的区别请参考:
1.https://blog.csdn.net/Caesar6666/article/details/104158047
2.https://segmentfault.com/a/1190000015645951
3.https://www.cnblogs.com/wyuzl/p/7745106.html
4.https://blog.csdn.net/yang_daxia/article/details/100084799?utm_medium=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

二、仿射变换

1.获得变换后的图像

详见下面代码示例

2.获得变换后的坐标
# 这里坐标参数格式为  [[x1,y1,x2,y2,x3,y3,x4,y4],... ]
def get_points(points_list,M):
    '''坐标转换'''
    for i in points_list:
        i[0], i[1] = [int(i) for i in list(np.dot(M, np.array([i[0], i[1], 1])))]
        i[2], i[3] = [int(i) for i in list(np.dot(M, np.array([i[2], i[3], 1])))]
        i[4], i[5] = [int(i) for i in list(np.dot(M, np.array([i[4], i[5], 1])))]
        i[6], i[7] = [int(i) for i in list(np.dot(M, np.array([i[6], i[7], 1])))]

    return points_list

代码示例

from PIL import Image


import numpy as np
import cv2
import math
import random
import matplotlib.pyplot  as plt

'''仿射变换'''

def perspective_transformation(Image,total_points_list):
    '''仿射变换'''
    h, w, ch = Image.shape  # 获取行数(高)和列数(宽)
    # 原图任意不在一条直线上的三个角的坐标
    pts1 = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1]])
    # 像素变化
    px_dif = random.randint(0, 50)
    # 期望得到的图像对应三个角坐标
    pts2 = np.float32([[0, 0], [px_dif, h - px_dif], [w - px_dif, h - px_dif]])

    # 获得变换矩阵
    M = cv2.getAffineTransform(pts1, pts2)
    # 应用
    dst = cv2.warpAffine(Image, M, (w, h))

    total_points_list = get_points(total_points_list,M)

    return dst,total_points_list

def get_points(points_list,M):
    '''坐标转换'''
    for i in points_list:
        i[0], i[1] = [int(i) for i in list(np.dot(M, np.array([i[0], i[1], 1])))]
        i[2], i[3] = [int(i) for i in list(np.dot(M, np.array([i[2], i[3], 1])))]
        i[4], i[5] = [int(i) for i in list(np.dot(M, np.array([i[4], i[5], 1])))]
        i[6], i[7] = [int(i) for i in list(np.dot(M, np.array([i[6], i[7], 1])))]

    return points_list



if __name__ == '__main__':
    image = cv2.imread('../myimages/2.jpg')
    # 图片原来的固有字段的坐标及值
    points_list = []
    with open('../myimages/gt_2.txt','r',encoding='utf-8') as f:
        for line in f.readlines():
            # 获取前8个元素,也就是四点坐标,后面的是文本内容,可以不用变
            data_line = line.split(',')
            # 将列表中坐标元素变成int
            data =  [ int(i) if data_line.index(i)<=7  else i for i in data_line]
            points_list.append(data)
    print(points_list)
    # 开始进行仿射变换
    new_image,points_list = perspective_transformation(image,points_list)
    # 将新的图片写在本地
    cv2.imwrite('new_image2.jpg',new_image)
    # 将新的坐标也写在本地
    f = open('new_image2.txt', 'w', encoding='utf-8')

    for lab in points_list:
        line = ",".join(str(i) for i in lab)
        f.write(line)
        f.write('\n')
    f.close()

    # 也可以在窗口查看效果
    plt.subplot(121), plt.imshow(image), plt.title('Input')
    plt.subplot(122), plt.imshow(new_image), plt.title('Output')
    plt.show()

运行结果:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容