【计算机视觉】OpenCV实现单目相机标定

这篇具有很好参考价值的文章主要介绍了【计算机视觉】OpenCV实现单目相机标定。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录

  • 单目相机标定(基于Python OpenCV)
    • 1.上期填坑
    • 2.单目相机标定
      • 2.1 数据采集
      • 2.2 角点提取
      • 2.3 参数求解
      • 2.4 参数评估(重投影误差)
      • 2.5 相机位姿(棋盘位姿)可视化
      • 2.6 同Matlab标定结果比较

单目相机标定(基于Python OpenCV)

1.上期填坑

在开始本篇博客之前,先填一下上一篇博客【计算机视觉】基于ORB角点+RANSAC算法实现图像全景拼接的坑(不算填吧,算做一个记录,因为并没有解决问题,留着看以后有没有空解决??),不想看的可以直接跳到下一节。

首先解决如何拼接多张图像(上篇博客只能拼接两张图像,多张图像需要保存两张图像的匹配结果,再重新读取计算角点)

改进的方法的基本思路是,仅计算当前两张图像的单应变换M_current,通过先前的单应矩阵M_before再计算一个累积变换,最终通过矩阵乘法得到的M的变换就延续了当前变换的累积变换矩阵:

    # 一开始无先前变换,因此设置为单位阵
    M_before = np.eye(3,3)
    result = cv2.imread('datas/1.jpg')
    # result = CalcUndistort(result, mtx, dist)
    result,_,_ = utils.auto_reshape(result, 1080)
    img2 = result
    cors2, desc2= extraORBfromImg(orb, img2)

    for i in range(1,6):
        print(i)
        img1 = cv2.imread('datas/'+str(i+1)+'.jpg')
        # img1 = CalcUndistort(img1, mtx, dist)
        img1,_,_ = utils.auto_reshape(img1, 1080)
        cors1, desc1= extraORBfromImg(orb, img1)
        
        match_dist, match_idx = ORBMatch(match, desc1, desc2)
        # 得到匹配点对的坐标
        match_pts = findMatchCord(match_idx, cors1, cors2)
        # 可视化匹配点
        # utils.drawMatches(img1, img2, cors1, cors2, match_idx)
        # RANSAC迭代去除异常点对
        update_match_pts = RANSAC(match_pts)
        # 最小二乘方法计算单应矩阵
        M = calc_homography(update_match_pts)
        # 图像拼接结果可视化, 并传递累积单应变换矩阵M ,返回先前累积拼接结果result
        result, M = homography_trans(M, M_before, img1, result)
        M_before = M
        # 不用再提取一遍:
        img2 = img1
        cors2, desc2 = cors1, desc1

值得注意的是,代码采用的匹配顺序是从右至左,为了保证每次只提取最左侧图像的角点,img1对于图像的拍摄时序应该要在img2的左侧

相应的,函数homography_trans也要做修改:

# 可视化图像对映射效果
def homography_trans(M, M_before, img1, img2):
    M = M_before @ M
    # out_img 第一张图像映射到第二张
    x_min, x_max, y_min, y_max, M2 = calc_border(M, img1.shape)
    # 透视变换+平移变换(使得图像在正中央)
    M = M2 @ M
    w, h = int(round(x_max)-round(x_min)), int(round(y_max)-round(y_min))
    out_img = cv2.warpPerspective(img1, M, (w, h))
    # print(out_img.shape)
    # cv2.imshow('ww',out_img)
    # cv2.waitKey(0)
    # 调整两张图像位姿一致:
    # x方向
    out_img_blank_x = np.zeros((out_img.shape[0], abs(round(x_min)), 3)).astype(np.uint8)
    img2_blank_x = np.zeros((img2.shape[0], abs(round(x_min)), 3)).astype(np.uint8)
    if(x_min>0):
        # print(1)
        out_img = cv2.hconcat((out_img_blank_x, out_img))
    if(x_min<0):
        # print(2)
        img2 = cv2.hconcat((img2_blank_x, img2))
    # y方向
    out_img_blank_y = np.zeros((abs(round(y_min)), out_img.shape[1], 3)).astype(np.uint8)
    img2_blank_y = np.zeros((abs(round(y_min)), img2.shape[1], 3)).astype(np.uint8)
    if(y_min>0):
        # print(3)
        out_img = cv2.vconcat((out_img, out_img_blank_y))
    if(y_min<0):
        # print(4)
        img2 = cv2.vconcat((img2_blank_y, img2))
    # 调整两张图像尺度一致(边缘填充):
    if(img2.shape[0]<out_img.shape[0]):
        blank_y = np.zeros((out_img.shape[0]-img2.shape[0], img2.shape[1], 3)).astype(np.uint8)
        img2 = cv2.vconcat((img2, blank_y)) 
    else:
        blank_y = np.zeros((img2.shape[0]-out_img.shape[0], out_img.shape[1], 3)).astype(np.uint8)
        out_img = cv2.vconcat((out_img, blank_y)) 
    if(img2.shape[1]<out_img.shape[1]):
        blank_x = np.zeros((img2.shape[0], out_img.shape[1]-img2.shape[1], 3)).astype(np.uint8)
        img2 = cv2.hconcat((img2, blank_x)) 
    else:
        blank_x = np.zeros((out_img.shape[0], img2.shape[1]-out_img.shape[1], 3)).astype(np.uint8)
        out_img = cv2.hconcat((out_img, blank_x))        

    # cv2.imwrite('out_img.jpg',out_img)
    # 叠加
    result = addMatches(out_img, img2)

    # 图像背景白
    mask = 255*np.ones(result.shape).astype(np.uint8)
    gray_res = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
    mask[gray_res==0]=0
    cv2.imwrite('mask.jpg',mask)
    # result[result==0]=255
    cv2.imwrite('result.jpg',result)
    return result, M

重点是改了这里(实现单应变换的传递):

... ...
M = M_before @ M
... ...
M = M2 @ M

(Ps:如果从左至右拼接,好像有点问题…)

然后另一个问题是:往后的拼接图像计算出的单应矩阵就会越扭曲:整一个视觉效果就会像文章来源地址https://www.toymoban.com/news/detail-416825.html

到了这里,关于【计算机视觉】OpenCV实现单目相机标定的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV快速入门:相机标定——单目视觉和双目视觉

    在当今科技日益发展的时代,计算机视觉作为人工智能的重要分支,已经深入到我们生活的各个领域。在这个广阔的领域中,相机标定是一个基础且关键的步骤,它直接影响到视觉系统的精度和效能。尤其是在单目视觉和双目视觉的应用中,准确的相机标定成为了实现高效和

    2024年02月05日
    浏览(45)
  • 【计算机视觉】基于OpenCV计算机视觉的摄像头测距技术设计与实现

    在当今技术日益进步的时代,计算机视觉已成为我们生活中不可或缺的一部分。从智能监控到虚拟现实,计算机视觉技术的应用范围日益广泛。在这篇博客中,我们将探索一个特别实用的计算机视觉案例:使用OpenCV实现摄像头测距。这一技术不仅对专业人士有用,也为编程爱

    2024年02月04日
    浏览(49)
  • 白学立体视觉(3): 单目相机标定

    小伙伴们,第一个理论加实践的小结来啦。本小节将会在白学立体视觉(2): 相机内外参数与坐标系的基础上,介绍一下鼎鼎有名的张正友标定法。 我们如果想重建出一台相机的成像过程的数学模型,相机的参数是最基本的。相机参数又分为内参和外参。那么内参和外参就是

    2024年02月06日
    浏览(47)
  • 【计算机视觉】---OpenCV实现物体追踪

    OpenCV中的物体追踪算法基于视觉目标跟踪的原理。物体追踪的目标是在连续的图像序列中定位和跟踪特定物体的位置。 在物体追踪中,我们需要对目标对象进行表示。通常使用边界框(bounding box)来表示目标的位置和大小。边界框是一个矩形区域,由左上角的坐标(x,y)和

    2024年02月08日
    浏览(49)
  • 计算机视觉实战项目2(单目测距+图像处理+路径规划+车牌识别)

    用python3+opencv3做的中国车牌识别,包括算法和客户端界面,只有2个文件,一个是界面代码,一个是算法代码,点击即可出结果,方便易用! 链接:车牌识别 大致的UI界面如下,点击输入图片,右侧即可出现结果! 额外说明:算法代码只有500行,测试中发现,车牌定位算法的

    2024年02月07日
    浏览(63)
  • 计算机视觉:使用opencv实现车牌识别

    汽车车牌识别(License Plate Recognition)是一个日常生活中的普遍应用,特别是在智能交通系统中,汽车牌照识别发挥了巨大的作用。汽车牌照的自动识别技术是把处理图像的方法与计算机的软件技术相连接在一起,以准确识别出车牌牌照的字符为目的,将识别出的数据传送至交

    2024年02月04日
    浏览(48)
  • 计算机视觉:使用opencv实现银行卡号识别

    OpenCV是Open Source Computer Vision Library(开源计算机视觉库)的简称,由Intel公司在1999年提出建立,现在由Willow Garage提供运行支持,它是一个高度开源发行的计算机视觉库,可以实现Windows、Linux、Mac等多平台的跨平台操作。opencv是一个用于图像处理、分析、机器视觉方面的开源函

    2024年02月05日
    浏览(46)
  • 计算机视觉之三维重建(二)(摄像机标定)

    标定示意图 标定目标 P ′ = M P w = K [ R   T ] P w P^{\\\'}=MP_w=K[R space T]P_w P ′ = M P w ​ = K [ R   T ] P w ​ 其中 K K K 为内参数, [ R   T ] [R space T] [ R   T ] 为外参数。该式子需要使用至少六对内外点对进行求解内外参数(11个未知参数)。 其中 R 3 × 3 , T 3 × 1 R_{3 times 3}, T_{3 times

    2024年02月12日
    浏览(47)
  • 【计算机视觉·OpenCV】使用Haar+Cascade实现人脸检测

    人脸检测的目标是找出图像中所有的人脸对应的位置,算法的输出是人脸的外接矩形在图像中的坐标。使用 haar 特征和 cascade 检测器进行人脸检测是一种传统的方式,下面将给出利用 OpenCV 中的 haarcascade 进行人脸检测的代码。 可选的人脸检测模型(区别是检测速度和精度不同

    2023年04月12日
    浏览(62)
  • 【计算机视觉】相机

    我的《计算机视觉》系列参考UC Berkeley的CS180课程,PPT可以在课程主页看到。 成像原理 想要拍一张相片,直接拿胶片对着景物肯定是不行的,因为物体的每一点发出的光线都会到达胶片上的每一点,从而导致胶片上的影像非常模糊,甚至什么都看不出来。因此,我们想建立景

    2024年02月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包