文章目录
- 前言
- 一、透射变换介绍:
- 二、opencv实现
- 2.1 cv2.getPerspectiveTransform()
- 2.2 cv2.warpPerspective()
- 三,代码实现:
- 四,矫正效果:
前言
在这个信息化时代,图像处理技术在众多领域发挥着越来越重要的作用。无论是自动驾驶、工业检测,还是医疗影像分析,都离不开对图像的精确识别和处理。在众多图像处理技术中,透射变换(Perspective Transform)无疑是一种非常实用的方法,它能够帮助我们校正因视角、镜头畸变等因素导致的图像失真。今天,我将带领大家走进透射变换的世界,探讨如何利用这一技术对仪表表盘进行校正,以便更准确地读取数据。
一、透射变换介绍:
图像的透射变换(Perspective Transformation),也常被称为投影变换或透视变换,是一种在二维图像中模拟三维空间中物体视角变化的几何变换。这种变换能够改变图像中物体的视角,使得我们可以从一个特定的角度观察物体,就像我们在现实世界中改变观察位置一样。
透射变换的主要特点和用途如下:
特点:
视角改变:透射变换能够模拟从不同角度观察同一物体的效果。例如,将一个俯视图转换为正视视图。
形状扭曲:与简单的旋转、缩放和平移不同,透射变换可以改变图像中物体的形状,使其呈现出不同的视角效果。
四边形到四边形的映射:透射变换通常涉及将图像中的一个四边形区域映射到另一个四边形区域。
用途:
图像校正:校正由于拍摄角度不正确导致的图像失真,如将倾斜的图像校正为水平视角。
视角变换:在计算机视觉中,变换图像以模拟从不同视角观察物体,这在自动驾驶、机器人导航等领域尤为重要。
图像拼接:将多个视角的图像拼接成一个宽广视角的图像,这在创建全景图像时非常有用。
虚拟现实:在虚拟现实和增强现实技术中,透射变换用于创建更加逼真的视角效果。
变换过程:
透射变换通常需要以下步骤:
确定对应点:在源图像和目标图像上分别确定四个对应的点。这四个点在源图像上定义了一个四边形区域,而在目标图像上定义了变换后的四边形区域。
计算变换矩阵:使用这四个点对,可以计算出透射变换矩阵。在OpenCV中,这可以通过cv2.getPerspectiveTransform()函数实现。
应用变换:使用计算出的变换矩阵,通过cv2.warpPerspective()函数将源图像变换到目标图像。
二、opencv实现
在opencv中要实现图像的透射变换需要三个步骤,首先定义源点和目标点,也就是定义源图像上的四个点和目标图像上的对应点,这些点将用于计算透射变换矩阵然后使用 cv2.getPerspectiveTransform() 函数来计算透射变换矩阵,最后使用cv2.warpPerspective() 函数来应用透射变换。
2.1 cv2.getPerspectiveTransform()
函数介绍:cv2.getPerspectiveTransform() 是 OpenCV 库中的一个函数,它用于计算从一个平面到另一个平面的透视变换矩阵。这个矩阵可以用来将图像中的点从一个四边形映射到另一个四边形,这在处理图像校正、视角变换等任务时非常有用。
输入:
src: 源图像中四边形的四个点,这是一个 4x2 数组,其中每一行代表一个点的坐标 (x, y)。
dst: 目标图像中对应的四边形的四个点,这也是一个 4x2 数组,与 src 中的点一一对应。
返回值
M: 返回一个 3x3 的浮点型透视变换矩阵。
注意:在提供源点和目标点时,点的顺序非常重要。通常,这些点应该按照顺时针或逆时针顺序排列,以确保变换的正确性。
2.2 cv2.warpPerspective()
函数介绍:
cv2.warpPerspective 是 OpenCV 库中的一个函数,它用于对图像应用透视变换。透视变换是一种二维图像变换,它模拟了三维空间中物体在不同视角下的外观。这种变换可以用来校正由于视角引起的图像扭曲,例如将一个倾斜的图像变换为正视图像。
输入:
src: 输入图像,可以是灰度图像或彩色图像。
M: 3x3 透视变换矩阵。
dsize: 输出图像的尺寸,格式为 (width, height)。
dst: 可选参数,输出图像。
flags: 插值方法标志。常见的插值方法包括:
cv2.INTER_LINEAR: 双线性插值(默认值)。
cv2.INTER_NEAREST: 最近邻插值。
cv2.INTER_AREA: 使用像素区域关系进行重采样。
cv2.INTER_CUBIC: 4x4 像素邻域的双三次插值。
borderMode: 边界像素外推方法,默认值为 cv2.BORDER_CONSTANT。
borderValue: 当 borderMode 为 cv2.BORDER_CONSTANT 时,这个值用于填充边界像素,默认为 0。
输出:
result: 变换后的图像。
注:透视变换通过cv2.getPerspectiveTransform函数计算得到矩阵M或手动指定,而输出图像尺寸由dsize参数决定,默认为(0, 0)时与变换后源图像尺寸一致。插值方法选择,如cv2.INTER_LINEAR,影响图像质量和计算效率。此外,borderMode和borderValue参数用于处理图像边界,确保变换后边界像素得到适当填充或外推。
三,代码实现:
一般情况下来说,表盘校正一般是跟在目标检测之后,目标检测标注时候只标注表盘区域如下图所示:
这样输入点即为目标检测输出的四个端点,我们的目的是让表盘尽可能为圆形,故校正的时候尝试将目标检测输出的矩形框校正为正方形即可,示例代码:
import cv2
import numpy as np
# 读取图像
image = cv2.imread(r'F:\traditional_vison\1691047616136.png')
height, width = image.shape[:2]
# 定义图像的四个端点坐标
top_left = [0, 0]
top_right = [width , 0]
bottom_right = [width , height ]
bottom_left = [0, height ]
h = max(height,width)
# 定义源图像中的四个点(透视变换前的点)
# 这里需要替换成你的实际坐标
pts1 = np.float32([top_left, top_right, bottom_right, bottom_left])
top_left2 = [0, 0]
top_right2 = [2*h , 0]
bottom_right2 = [2*h , 2*h ]
bottom_left2 = [0, 2*h ]
# 定义目标图像中的四个点(透视变换后的点)
# 这里需要替换成你的实际坐标
pts2 = np.float32([top_left2, top_right2, bottom_right2, bottom_left2])
# 计算透射变换矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)
# 应用透射变换
transformed_image = cv2.warpPerspective(image, M, (2000, 2000))
# 显示原始图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', transformed_image)
# 保存变换后的图像
cv2.imwrite('transformed_image.jpg', transformed_image)
# 等待按键后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
注:效果更好的方法可以尝试用二值化分割表盘,获取表盘的椭圆形蒙版,根据椭圆形的长轴和短轴来将表盘仿射为圆形表盘。