当前位置:   article > 正文

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表示列数

 代码如下所示:

  1. import cv2
  2. import numpy as np
  3. #图像输入
  4. src = cv2.imread("E:/pythonProject/color.png")
  5. #获取图像shape
  6. rows, cols = src.shape[: 2]
  7. #设置图像仿射变化矩阵
  8. post1 = np.float32([[50, 50], [200, 50], [50, 200]])
  9. post2 = np.float32([[10, 100], [200, 50], [100,250]])
  10. M = cv2.getAffineTransform(post1, post2)
  11. #图像变换
  12. result = cv2.warpAffine(src, M, (rows, cols))
  13. #图像显示
  14. cv2.imshow("result", result)
  15. cv2.imshow("scr", src)
  16. #等待窗口
  17. cv2.waitKey(0)
  18. 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表示列数

代码如下所示:

  1. import cv2
  2. import numpy as np
  3. #读取图片
  4. src = cv2.imread("E:/pythonProject/color.png")
  5. #获取图像shape
  6. rows, cols = src.shape[: 2]
  7. #设置透视变换图像矩阵
  8. post1 = np.float32([[55, 65], [288, 49], [28, 237], [239,240]])
  9. post2 = np.float32([[0, 0], [200, 0], [0, 200], [200, 200]])
  10. M = cv2.getPerspectiveTransform(post1, post2)
  11. #图像变换
  12. result = cv2.warpPerspective(src, M, (200, 200))
  13. #图像显示
  14. cv2.imshow("scr", src)
  15. cv2.imshow("result", result)
  16. #等待窗口
  17. cv2.waitKey(0)
  18. 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)
  1. for x1, y1, x2, y2 in lines[1]:
  2. cv2.line(result1, (x1,y1), (x2, y2), (255, 0, 0), 2)
  3. print((x1, y1), (x2, y2))
  4. for x1, y1, x2, y2 in lines[0]:
  5. cv2.line(result1, (x1,y1), (x2, y2), (0, 0, 255), 2)
  6. print((x1, y1), (x2, y2))

输出结果如下所示:

校正输出结果如下所示:

 

完整代码如下所示:

  1. import cv2
  2. #图像输入
  3. image = cv2.imread('E:/pythonProject/000.jpg')
  4. result1 = image.copy()
  5. result2 = image.copy()
  6. result3 = image.copy()
  7. #高斯模糊
  8. img = cv2.GaussianBlur(image, (3, 3), 0)
  9. #转为灰度图像
  10. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  11. #边缘检测
  12. edges = cv2.Canny(gray, 50, 150, apertureSize=3)
  13. #霍夫变换
  14. lines = cv2.HoughLinesP(edges, 1, np.pi/180, 160, lines= None, minLineLength= 90, maxLineGap=10)
  15. print(lines)
  16. for x1, y1, x2, y2 in lines[1]:
  17. cv2.line(result1, (x1,y1), (x2, y2), (255, 0, 0), 2)
  18. print((x1, y1), (x2, y2))
  19. for x1, y1, x2, y2 in lines[0]:
  20. cv2.line(result1, (x1,y1), (x2, y2), (0, 0, 255), 2)
  21. print((x1, y1), (x2, y2))
  22. post1 = np.float32([[207, 152], [517, 285],[17, 600],[394, 591] ])
  23. post2 = np.float32([[0,0],[284, 0], [0, 487], [284, 487]])
  24. M = cv2.getPerspectiveTransform(post1, post2)
  25. result = cv2.warpPerspective(result3, M, (284,487))
  26. cv2.imshow("result", result)
  27. cv2.imshow("edges", edges)
  28. cv2.imshow("result1", result1)
  29. # 图像输出
  30. cv2.imshow("gray", gray)
  31. cv2.imshow("image", image)
  32. # 等待窗口
  33. cv2.waitKey(0)
  34. cv2.destroyAllWindows()
  35. #写入文件
  36. cv2.imwrite("E:/pythonProject/gray.jpg",gray)
  37. cv2.imwrite("E:/pythonProject/edges.jpg",edges)
  38. cv2.imwrite("E:/pythonProject/rusult1.jpg", result1)
  39. cv2.imwrite("E:/pythonProject/rusult.jpg", result)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/100303
推荐阅读
相关标签
  

闽ICP备14008679号