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()
网友评论