畸变问题解决

本文详细介绍了摄像机成像的原理,包括坐标转换和相机内外参数。接着讨论了图像畸变的类型,如径向和切向畸变,并提出了畸变校正的步骤,如使用棋盘图标定、计算畸变系数和内参数。文章还提供了OpenCV的畸变矫正代码示例,涉及相机标定和反畸变计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.摄像机成像原理

2.成像畸变

3.畸变解决方案

4.当前畸变问题解决情况

1.摄像机成像原理

摄像机成像的过程实质上是坐标系的转换,空间中的点从世界坐标系转换到摄像机坐标系,然后再投影到图像坐标系(成像平面),再将数据转换到图像坐标系。具体转换如下:

转换的数学表达式如下所示:

RT01矩阵:相机外参,是相机相对于世界坐标系的旋转和平移变换关系。

3*3矩阵:相机内参,是相机的固有属性,含有焦距、像元尺寸等参数。

2.成像畸变

图像的畸变主要有两种:径向畸变切向畸变

径向畸变:正中心位置的畸变最小,随着半径的增大,畸变增大。径向畸变可以分为枕形畸变和桶形畸变:

切向畸变:在透镜与成像平面不平行时就会产生,类似于透视变换。

3.畸变解决方案

本次主要解决横向畸变情况,主要包括以下步骤

1.通过标定板(棋盘图)采集图像,尽量在视野范围内多采集不同角度不同位置的图片;

2.提取标定图片的角点信息;

3.进一步获取标定图片的亚像素点信息;

4.在棋盘图上绘制找到的内角点(尽量使用长款不同的标定板,以便模型更好识别横向和纵向);

5.利用算法模型计算畸变系数,内参数,外参数(平移参数,旋转参数);

6.使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数;

6.对未标定图片进行畸变矫正;

7.通过反投影误差评估矫正的好坏。

4.当前畸变问题解决情况

参考

import cv2
import numpy as np
 
def rectify_video(image, map1, map2):
    frame_rectified = cv2.remap(image, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
    return frame_rectified
 
 
def calculate_para(K, D, width, height):
    # 优化内参数和畸变系数
    p = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, (width, height), None)
    # 此处计算花费时间较大,需从循环中抽取出来
    map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, None, p, (width, height), cv2.CV_32F)
    return map1, map2
 
def main():
    # K D 参数
    K = np.array(
        [[1201.3967181633418, 0.0, 909.7424436183744], [0.0, 1203.635467250557, 534.1590658991514], [0.0, 0.0, 1.0]])
    D = np.array([[-0.0978537375125563], [-0.03841501213366177], [-0.03612764818273854], [0.05276041355808103]])
    width, height = 1920, 1080
    # 参数优化
    map1, map2 = calculate_para(K, D, width, height)
 
    video = cv2.VideoCapture("filename.jpg")
    while (video.isOpened()):
        success, image = video.read()
        if not success:
            break
        # 畸变矫正
        frame = rectify_video(image, map1, map2)
        frame = cv2.resize(frame, (960, 540))
        cv2.imshow('frame', frame)
        if cv2.waitKey(0) & 0xFF == ord('q'):
            break
    video.release()
    cv2.destroyAllWindows()
 
if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

范纹杉好好生活工作

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值