700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > python图像处理(十)——图像仿射变换 图像透视变换和图像校正

python图像处理(十)——图像仿射变换 图像透视变换和图像校正

时间:2020-03-19 02:44:58

相关推荐

python图像处理(十)——图像仿射变换 图像透视变换和图像校正

一、图像仿射变换

1.原理

仿射变换(Affine Transformation 或Affine Map)是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,转换过程坐标点的相对位置和属性不发生变换,是一个线性变换,该过程只发生旋转和平移过程。因此,一个平行四边形经过仿射变换后还是一个平行四边形。所以,仿射= 旋转 + 平移。其数学表达式形式如下:

对应的齐次坐标矩阵表示形式为:

仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)。非共线的三对对应点确定一个唯一的仿射变换。图像的旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,opencv提供了根据变换前后三个点的对应关系来自动求解M。这个函数是M=cv2.getAffineTransform(pos1,pos2),其中两个位置就是变换前后的对应位置关系。输出的就是仿射矩阵M。然后在使用函数cv2.warpAffine()。

2.函数原型

仿射变换的函数原型如下:

M = cv2.getAffineTransform(post1, post2)

post1 = 表示变换前的位置post2 = 表示变换后的位置

cv2.warpAffine(src, M, (cols, rows))

src表示原始图像M表示仿射变换矩阵(rows, cols)表示变换后的图像大小,rows表示行数,cols表示列数

代码如下所示:

import cv2import numpy as np#图像输入src = cv2.imread("E:/pythonProject/color.png")#获取图像shaperows, cols = src.shape[: 2]#设置图像仿射变化矩阵post1 = np.float32([[50, 50], [200, 50], [50, 200]])post2 = np.float32([[10, 100], [200, 50], [100,250]])M = cv2.getAffineTransform(post1, post2)#图像变换result = cv2.warpAffine(src, M, (rows, cols))#图像显示cv2.imshow("result", result)cv2.imshow("scr", src)#等待窗口cv2.waitKey(0)cv2.destroyAllWindows()

输出结果如下所示:

二、图像透视变换

1.原理

透视变换是把一个图像投影到一个新的视平面的过程,该过程包括:把一个二维坐标系转换为三维坐标系,然后把三维坐标系投影到新的二维坐标系。该过程是一个非线性变换过程,因此,一个平行四边形经过透视变换后只得到四边形,但不平行。

透视需要的是一个3*3的矩阵,同理opencv在构造这个矩阵的时候还是采用一种点对应的关系来通过函数自己寻找的,因为我们自己很难计算出来。这个函数是M = cv2.getPerspectiveTransform(pts1,pts2),其中pts需要变换前后的4个点对应位置。得到M后在通过函数cv2.warpPerspective(img,M,(200,200))进行。

2.函数原型

透射变换函数原型如下:

M = cv2.getPerspectiveTransform(post1, post2)

post1表示投射变换前4个点对应的位置post2表示投射变换后4个点对应的位置

cv2.warpPerspective(src, M, (cols, rows))

src表示原始图像M表示仿射变换矩阵(rows, cols)表示变换后的图像大小,rows表示行数,cols表示列数

代码如下所示:

import cv2import numpy as np#读取图片src = cv2.imread("E:/pythonProject/color.png")#获取图像shaperows, cols = src.shape[: 2]#设置透视变换图像矩阵post1 = np.float32([[55, 65], [288, 49], [28, 237], [239,240]])post2 = np.float32([[0, 0], [200, 0], [0, 200], [200, 200]])M = cv2.getPerspectiveTransform(post1, post2)#图像变换result = cv2.warpPerspective(src, M, (200, 200))#图像显示cv2.imshow("scr", src)cv2.imshow("result", result)#等待窗口cv2.waitKey(0)cv2.destroyAllWindows()

输出结果如下所示:

三、基于图像透视变换的的图像校正

参考大神文章,通过图像透视实现图像的校正。一张图像中有一张A4纸,通过图像处理的方法将其校正。

其大致思路如下:

先将图像进行高斯模糊,然后将其转换为灰度图像,方便转换。然后用Canny算子进行边缘检测,检测出图像边缘信息,然后通过霍夫变换得到A4纸边缘(可以看到A4纸中还有A4纸外有一些线,可以通过霍夫变换来去掉这些线)得到A4纸的边缘线条,最后进行图像透视变换得到图像校正目的。

完整代码如下所示:

转换为灰度图像:

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

输出的灰度处理后的图像:

边缘检测:

edges = cv2.Canny(gray, 50, 150, apertureSize=3)

输出结果如下所示:

霍夫变换得到边缘:

lines = cv2.HoughLinesP(edges, 1, np.pi/180, 160, lines= None, minLineLength= 90, maxLineGap=10)

for x1, y1, x2, y2 in lines[1]:cv2.line(result1, (x1,y1), (x2, y2), (255, 0, 0), 2)print((x1, y1), (x2, y2))for x1, y1, x2, y2 in lines[0]:cv2.line(result1, (x1,y1), (x2, y2), (0, 0, 255), 2)print((x1, y1), (x2, y2))

输出结果如下所示:

校正输出结果如下所示:

完整代码如下所示:

import cv2#图像输入image = cv2.imread('E:/pythonProject/000.jpg')result1 = image.copy()result2 = image.copy()result3 = image.copy()#高斯模糊img = cv2.GaussianBlur(image, (3, 3), 0)#转为灰度图像gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#边缘检测edges = cv2.Canny(gray, 50, 150, apertureSize=3)#霍夫变换lines = cv2.HoughLinesP(edges, 1, np.pi/180, 160, lines= None, minLineLength= 90, maxLineGap=10)print(lines)for x1, y1, x2, y2 in lines[1]:cv2.line(result1, (x1,y1), (x2, y2), (255, 0, 0), 2)print((x1, y1), (x2, y2))for x1, y1, x2, y2 in lines[0]:cv2.line(result1, (x1,y1), (x2, y2), (0, 0, 255), 2)print((x1, y1), (x2, y2))post1 = np.float32([[207, 152], [517, 285],[17, 600],[394, 591] ])post2 = np.float32([[0,0],[284, 0], [0, 487], [284, 487]])M = cv2.getPerspectiveTransform(post1, post2)result = cv2.warpPerspective(result3, M, (284,487))cv2.imshow("result", result)cv2.imshow("edges", edges)cv2.imshow("result1", result1)# 图像输出cv2.imshow("gray", gray)cv2.imshow("image", image)# 等待窗口cv2.waitKey(0)cv2.destroyAllWindows()#写入文件cv2.imwrite("E:/pythonProject/gray.jpg",gray)cv2.imwrite("E:/pythonProject/edges.jpg",edges)cv2.imwrite("E:/pythonProject/rusult1.jpg", result1)cv2.imwrite("E:/pythonProject/rusult.jpg", result)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。