一、图像矫正

        仿射变换是把一个二维坐标系转换到另一个二 维坐标系的过程,转换过程坐标点的相对位置和属性不发生变换,是一个线性变换,该过程只发生旋转 和平移过程。因此,一个平行四边形经过仿射变换后还是一个平行四边形。

        图像矫正的原理是透视变换,透视变换是把一个图像投影到一个新的视平面的过程,在现实世界中,我们观察到的物体在视觉上会 受到透视效果的影响,即远处的物体看起来会比近处的物体小。透视投影是指将三维空间中的物体投影 到二维平面上的过程,这个过程会导致物体在图像中出现形变和透视畸变。透视变换可以通过数学模型 来校正这种透视畸变,使得图像中的物体看起来更符合我们的直观感受。通俗的讲,透视变换的作用其 实就是改变一下图像里的目标物体的被观察的视角。

        如上图所示,左图在经过透视变换后得到了右图的结果,带入上面的话就是图像中的车道线(目标物 体)的被观察视角从平视视角变成了俯视视角,这就是透视变换的作用。

        其中x、y是原始图像点的坐标,x^{​{}'}y^{​{}'} 是变换后的坐标,a11,a12,…,a33则是一些旋转量和平移量, 由于透视变换矩阵的推导涉及三维的转换,所以这里不具体研究该矩阵,只要会使用就行,而OpenCV 里也提供了getPerspectiveTransform()函数用来生成该3*3的透视变换矩阵。

在该函数中,需要提供两个参数:

        src:原图像上需要进行透视变化的四个点的坐标,这四个点用于定义一个原图中的四边形区域。

        dst:透视变换后,src的四个点在新目标图像的四个新坐标。

该函数会返回一个透视变换矩阵,得到透视变化矩阵之后,使用warpPerspective()函数即可进行透视变 化计算,并得到新的图像。该函数需要提供如下参数:

        src:输入图像。

        M:透视变换矩阵。这个矩阵可以通过getPerspectiveTransform函数计算得到。

        dsize:输出图像的大小。它可以是一个Size对象,也可以是一个二元组。

        flags:插值方法的标记。

        borderMode:边界填充的模式。 

导入模块

import cv2
import numpy as np

输入图像

img=cv2.imread('care.png')

 查找点坐标

points1=np.float32([[185,90], [540,135],[110,310], [520,355]])
points2=np.float32([[0,0],[img.shape[1],0],[0,img.shape[0]],[img.shape[1],img.shape[0]]])

根据点坐标绘线(选绘)

cv2.line(img, [178,90], [540,135], color=(0,0,255),thickness=1, lineType=cv2.LINE_AA)
cv2.line(img, [110,310], [520,355], color=(0,0,255),thickness=1, lineType=cv2.LINE_AA)

cv2.line(img, [178,90], [110,310], color=(0,0,255),thickness=1, lineType=cv2.LINE_AA)
cv2.line(img, [540,135], [520,355], color=(0,0,255),thickness=1, lineType=cv2.LINE_AA)

 ​​​

透视变换矩阵

M=cv2.getPerspectiveTransform(points1,points2)

图像校正

img_warpP=cv2.warpPerspective(img,M,(img.shape[1],img.shape[0]))

完整代码

import cv2  # 导入OpenCV库  
import numpy as np  # 导入NumPy库,用于数组处理  

# 读取图像  
img = cv2.imread('care.png')  

# 定义透视变换前的四个点坐标 (原图中的对应坐标)  
points1 = np.float32([[185, 90], [540, 135], [110, 310], [520, 355]])  

# 定义透视变换后的四个点坐标 (目标图像中的坐标)  
points2 = np.float32([[0, 0], [img.shape[1], 0], [0, img.shape[0]], [img.shape[1], img.shape[0]]])  

# 在图像上绘制四条红色线段,便于视图对比  
cv2.line(img, [178, 90], [540, 135], color=(0, 0, 255), thickness=1, lineType=cv2.LINE_AA)  # 第1条线  
cv2.line(img, [110, 310], [520, 355], color=(0, 0, 255), thickness=1, lineType=cv2.LINE_AA)  # 第2条线  
cv2.line(img, [178, 90], [110, 310], color=(0, 0, 255), thickness=1, lineType=cv2.LINE_AA)  # 第3条线  
cv2.line(img, [540, 135], [520, 355], color=(0, 0, 255), thickness=1, lineType=cv2.LINE_AA)  # 第4条线  

# 计算透视变换矩阵  
M = cv2.getPerspectiveTransform(points1, points2)  

# 应用透视变换,得到变换后的图像  
img_warpP = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))  

# 显示原图像  
cv2.imshow('img', img)  

# 显示透视变换后的图像  
cv2.imshow('img_warpP', img_warpP)  

# 等待用户按键后关闭窗口  
cv2.waitKey(0)  

二、库函数 

2.1、line()

cv.line(	img, pt1, pt2, color[, thickness[, lineType[, shift]]]	) ->	IMG
方法 描述
img 该图像
pt1 线段的第一个点
pt2 线段的第二个点
color 线条颜色
thickness 线条粗细
lineType 线路的类型。请参见 LineTypes
shift 点坐标中的小数位数

2.2、getPerspectiveTransform()

cv.getPerspectiveTransform(	src, dst[, solveMethod]	) ->	retval
方法 描述
src 源图像中四边形顶点的坐标。
dst 目标图像中相应四边形顶点的坐标。
solveMethod 传递给 cv::solve 的方法 (DecompTypes)

2.3、warpPerspective()

cv.warpPerspective(	src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]	) ->	DST
方法 描述
src 输入图像
dst 输出图像,其大小为 dsize 且类型与 src 相同
M 3*3变换矩阵
dsize 输出图像的大小
flags 插值方法(INTER_LINEAR 或 INTER_NEAREST)和可选标志 WARP_INVERSE_MAP 的组合,将 M 设置为逆变换
borderMode 像素外插法(BORDER_CONSTANT 或 BORDER_REPLICATE)。
borderValue 在恒定边界的情况下使用的值;默认情况下,它等于 0
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐