opencv双目视觉标定,激光结构光提取,指定特征点获取世界坐标

2023-11-15

双目视觉标定,激光结构光提取,指定特征点获取世界坐标


这学期在做双目视觉方面的事情,因为没人带,自己一个人踩了很多坑,因此在这写一点自己的总结心得。

标定方面

首先标定主要就是为了确定左右相机的内参和两个相机之间的旋转跟平移矩阵,这些参数都是后面需要用到的,而网上关于标定的文章太多了,本人试过opencv的标定,也试过matlab的标定方法,最后感觉还是matlab的比较准确,主要步骤可以参考下面这篇文章,写的挺详细了:
双目标定

校正

在校正这方面我主要采用的是opencv中的Bouguet算法,其用处简单来说就是使你的两个相机成为光轴平行的模型,如下图分别为校正前和校正后。
在这里插入图片描述在这里插入图片描述
并且校正后会使得图片的极线对齐,所谓极线对齐,简单理解就是对齐后的左右图片的特征点会在同一行像素行上,如下图:
在这里插入图片描述
在这里插入图片描述
可以看到校正后左边图片上的一点跟右图上对应的一点在同一行上。这一步方便后续的立体匹配也就是特征点的匹配,首先我们得知道立体视觉中最重要的部分就是寻找特征点,所有做的一切都是为了特征点的匹配而做的,试想你在左图上确定一点初始点,要在右图上找到其对应的点,那么就只要沿着初始点的行横向搜索匹配就可以,或者在这一行的附近几行搜索,大大减少了计算量。

结构光提取

因为笔者做的实验是为了计算一个物体的角度,因此用激光照射来辅助提取特征点,并且我只需要获取三个点的世界坐标就能测出角度。如下图,黑点就是我所需要的特征点:
在这里插入图片描述

因此我要对激光进行骨架提取,首先进行图片预处理,主要步骤就是先把左右图转换为灰度图,然后进行图片校正获取校正后的左右图片,再进行高斯滤波,然后阈值分解,所得到的左右图效果图如下:
在这里插入图片描述
在这里插入图片描述
最后就使劲结构光的提取。
在这一步我试过很多方法,也踩过很多坑,比如steger方法,灰度重心法,极值法,方向模板法,脊线跟踪法等,其中steger和脊线主要都是应用海塞矩阵来选择光电,但是笔者在实际中的实验效果却不太理想,不知道是海塞矩阵的问题还是激光的问题,最后根据实际情况选择了方向模板法,python代码如下:

def direction(img):
    K1 = np.array([[0,0,1,1,1,0,0],
                   [0, 0, 1, 1, 1, 0, 0],
                   [0, 0, 1, 1, 1, 0, 0],
                   [0, 0, 1, 1, 1, 0, 0],
                   [0, 0, 1, 1, 1, 0, 0]])
    K2 = np.array([[0,0,0,0,0,0,0],
                   [0, 1, 1, 1, 1, 1, 0],
                   [0, 1, 1, 1, 1, 1, 0],
                   [0, 1, 1, 1, 1, 1, 0],
                   [0, 0, 0, 0, 0, 0, 0]])
    K3 = np.array([[1, 1, 1, 0, 0, 0, 0],
                   [0, 1, 1, 1, 0, 0, 0],
                   [0, 0, 1, 1, 1, 0, 0],
                   [0, 0, 0, 1, 1, 1, 0],
                   [0, 0, 0, 0, 1, 1, 1]])
    K4 = np.fliplr(K3)

    M1 = cv.filter2D(img, cv.CV_32FC1, K1)
    M2 = cv.filter2D(img, cv.CV_32FC1, K2)
    M3 = cv.filter2D(img, cv.CV_32FC1, K3)
    M4 = cv.filter2D(img, cv.CV_32FC1, K4)

    maxindex = 0
    maxvalue = 0
    x = 0
    y = 0
    Pt = []
    col = img.shape[1]
    row = img.shape[0]
    for i in range(col):
        flag = False
        for j in range(row):
            if img[j, i] > 200:
                maxvalue = max(M1[j,i],M2[j,i],M3[j,i],M4[j,i])
                if(maxvalue>=maxindex):
                    x = i
                    y = j
                    flag = True

        if(flag):
            Pt.append(x)
            Pt.append(y)

    new_img = np.zeros(img.shape, dtype=np.uint8)
    for k in range((int(len(Pt) / 2))):
        new_img[Pt[2 * k + 1], Pt[2 * k]] = 255
    return new_img

方向模板法主要原理简单讲就是根据几个预先制定的模板对每一行或者每一列进行匹配,然后将值最大的那个点做为主光点,详细的可以去看相关论文,另外还有自适应方向模板法,具体原理其实都差不多。
提取完后的效果图如下:
在这里插入图片描述
在这里插入图片描述
可以看到总体效果还是可以的。
最后我觉得这一步的前提还是在阈值分割,只有将感兴趣的区域选择出来,对后续的工作才能有所帮助。

二维点转换为三维点

二维点的获取就是特征点的获取,因为的需求很简单, 只需要左右两个点和拐点就行,因此提取很简单,就不发出来了,主要说一下特征点是如何获得三维点的。
简单说就是根据前面的标定获得Q矩阵,即重投影矩阵,再根据重投影矩阵反求坐标

def getAngle(A1,B1,C1,A2,B2,C2):
    Q = c_config.Q
    print(Q)


    cx = Q[0][3]
    cy = Q[1][3]
    print("cx = ", cx)
    print("cy =", cy)
    f = Q[2][3]
    E = Q[3][3]
    Tx = Q[3][2]
    # Tx = 0.008333333
    # Tx = 0.01667
    print(f)
    print(Tx)
    print(E)
    print("1=",A1,B1,C1)
    print("2=", A2, B2, C2)
    deep = np.array([A1[1]-A2[1],B1[1]-B2[1] , C1[1]-C2[1]])
    print("deep=",deep)
    w = deep * Tx + E
    Z = f / w

    y = np.array([A1[0], B1[0], C1[0]])
    x = np.array([A1[1], B1[1], C1[1]])

    X = (x + cx)/w

    Y = (y + cy)/w

    T = np.vstack((X, Y, Z)).T
    print("T= ", T)


    print(T[0])
    print(T[1])
    print(T[2])
    A = np.array([T[0][0], T[0][1], T[0][2]])
    B = np.array([T[1][0], T[1][1], T[1][2]])
    C = np.array([T[2][0], T[2][1], T[2][2]])
    BA = A-B
    BC = C-B
    print(BA, BC)
    print(A,B,C)

    cosangle = BA.dot(BC) / (np.linalg.norm(BA) * np.linalg.norm(BC))
    # cosangle = cos_dist(BA,BC)
    Lba = np.sum(np.linalg.norm(BA))
    Lbc = np.sum(np.linalg.norm(BC))
    print("BA.BC=",BA.dot(BC))
    print("Lba=", Lba)
    print("Lbc=", Lbc)
    print("cos=", cosangle)
    angle = np.arccos(cosangle)
    print(np.degrees(angle))

    ax = plt.subplot(111, projection='3d')  # 创建一个三维的绘图工程
    #  将数据点分成三部分画,在颜色上有区分度
    ax.scatter(T[0][0], T[0][1], T[0][2], c='y')  # 绘制数据点
    ax.scatter(T[1][0], T[1][1], T[1][2], c='r')
    ax.scatter(T[2][0], T[2][1], T[2][2], c='g')

    ax.plot([A[0], B[0], C[0]], [A[1], B[1], C[1]], [A[2], B[2], C[2]], label='parametric curve')

    ax.set_zlabel('Z')  # 坐标轴
    ax.set_ylabel('Y')
    ax.set_xlabel('X')
    plt.show()

重投影矩阵Q实现了世界坐标系{world}和像素坐标系{pixel}之间的转换。具体如下:
在这里插入图片描述
这里Q矩阵中的参数都是左相机的参数,除了Cx‘以外,但一般校正正确后,Cx = Cx’,所以Q矩阵的最后一项为0,然后用左图片的特征点跟视差求得三维坐标,并且这里默认世界坐标系是跟左相机坐标系重合的,如下:所示

在这里插入图片描述
其中d = Xl - Xr,Xl为左图片点像素坐标,Xr为右图片点像素坐标。
至此,就能获得特征点三维坐标。

总结

对越角度计算来说,最主要的还是特征点的提取,只有特征点提取正确,才能获取正确的世界坐标,而提取在特征点的前提就是要有较好的结构光骨架,因此对结构光的骨架提取要求很高。其实总的来说就是一点点小东西,但因为都是一个人在做,所以在实验的时候还是绕了很多弯路,踩了很多坑,因此写此文以简单总结一下个人心得,希望能帮助到一点进来看本文的你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv双目视觉标定,激光结构光提取,指定特征点获取世界坐标 的相关文章

  • 使用Python的工业视觉相机[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何将输出视频保存到 OpenCV 中的文件中

    我想将输出视频保存到文件中而不是显示它并尝试使用 cvcaptureimage 但仍然无法获得结果 include
  • 检查图像中是否有太薄的区域

    我正在尝试验证雕刻机的黑白图像 更多的是剪贴画图像 不是照片 我需要考虑的主要事情之一是区域的大小 或线条的宽度 因为机器无法处理太细的线条 所以我需要找到比给定阈值更细的区域 以此图为例 竖琴的琴弦可能太细而无法雕刻 我正在阅读有关 Ma
  • OpenCV C++ 如何知道每行的轮廓数进行排序?

    我有一个二值图像 https i stack imgur com NRLVv jpg在这张图片中 我可以使用重载的函数轻松地对从上到下 从左到右找到的轮廓进行排序std sort 我首先通过以下方式从上到下排序 sort contours
  • ffmpeg AVFrame 到 opencv Mat 转换

    我目前正在开发一个使用 ffmpeg 解码接收到的帧的项目 解码后 我想将 AVFrame 转换为 opencv Mat 帧 以便我可以在 imShow 函数上播放它 我拥有的是字节流 我将其读入缓冲区 解码为 AVFrame f fope
  • 从图像坐标获取对象的世界坐标

    I have been following this http docs opencv org modules calib3d doc camera calibration and 3d reconstruction html docume
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • opencv人脸检测示例

    当我在设备上运行应用程序时 应用程序崩溃并显示以下按摩 java lang UnsatisfiedLinkError 无法加载 detector based tracker findLibrary 返回 null 我正在使用 OpenCV
  • 在 Python 中将 OpenCV 帧流式传输为 HTML

    我正在尝试从 opencv Pyt hon 中的 URL 读取视频 然后逐帧处理它 然后将其发送到 HTML 页面 But I am only getting the first frame after that the program g
  • cv2.drawContours() - 取消填充字符内的圆圈(Python,OpenCV)

    根据 Silencer的建议 我使用了他发布的代码here https stackoverflow com questions 48244328 copy shape to blank canvas opencv python 482465
  • 在 Visual Studio 2012 中安装 OpenCV

    我正在尝试安装 OpenCV 来与 Visual Studio 一起使用 我使用的是2012Pro版本 但我认为它应该与vs10相同 我正在关注这个教程 http docs opencv org doc tutorials introduc
  • 是否可以在 PyScript 中使用 OpenCV 模块?

    我想使用 opencv 模块 但无法导入 OpenCV 那么我该如何解决这个问题呢 顺便说一句 Pyodide 支持 OpenCV 示例代码 https i stack imgur com ahwex jpg 尚不支持 OpenCV 此时O
  • OpenCV 2.2 和多 CPU - opencv_haartraining.exe 是多线程的吗?

    我在 VS 2010 上构建了 OpenCV 2 2 启用了 TBB 3 支持 我确保所有项目都有正确的 tbb lib 目录 并将 tbb lib 列为依赖项 通过隐藏 tbb dll 进行验证 果然 haartraining exe 抱
  • BRISK 特征检测器检测零个关键点

    下面显示的 Brisk 探测器没有给我任何关键点 有人可以提出一个问题吗 我将尝试用一些代码解释我在下面所做的事情 include opencv2 features2d features2d hpp using namespace cv u
  • 如何使用 AdaBoost 进行特征选择?

    我想使用 AdaBoost 从大量 100k 中选择一组好的特征 AdaBoost 的工作原理是迭代功能集并根据功能的执行情况添加功能 它选择对现有特征集错误分类的样本表现良好的特征 我目前正在 Open CV 中使用CvBoost 我得到
  • 如何加速 svm.predict?

    我正在编写一个滑动窗口来提取特征并将其输入到 CvSVM 的预测函数中 然而 我偶然发现 svm predict 函数相对较慢 基本上 窗口以固定的步幅长度在图像比例上滑动穿过图像 遍历图像加上提取每个图像特征的速度 窗口大约需要 1000
  • 使用卡尔曼滤波器跟踪位置和速度

    我正在使用卡尔曼滤波器 恒定速度模型 来跟踪物体的位置和速度 我测量对象的 x y 并跟踪 x y vx vy 这是有效的 但是如果在传感器读数 x y vx vy 上添加 20 mm 的高斯噪声 即使该点没有移动 只是噪声也会发生波动 对
  • 如何检测图像是否像素化

    之前有人在 SO 上提出过这样的问题 在Python中检测像素化图像 https stackoverflow com questions 12942365 detecting a pixelated image in python还有关于q
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 如何使用 python 定位和读取 Data Matrix 代码

    我正在尝试读取微管底部的数据矩阵条形码 我试过libdmtx http libdmtx sourceforge net 它有 python 绑定 当矩阵的点是方形时工作得相当好 但当矩阵的点是圆形时工作得更糟 如下所示 另一个复杂问题是在某

随机推荐

  • 交换机的Access口与Trunk口

    基本概念 Access类型的端口只能属于1个VLAN 一般用于连接计算机的端口 Trunk类型的端口可以允许多个VLAN通过 可以接收和发送多个VLAN的报文 一般用于交换机之间连接的端口 处理流程 Acess端口收报文 收到一个报文 判断
  • Python 分割技术提取图像和视频中对象

    计算机视觉是计算机查看和识别对象的媒介 计算机视觉的目标是使计算机能够分析图像和视频中的对象 解决不同的视觉问题 对象分割为方便分析图像和视频中的对象铺平了道路 对不同领域做出了巨大贡献 例如医学 自动驾驶汽车的视觉以及图像和视频的背景编辑
  • vue form 滑动验证码、手机短信验证

    话不多说直接上效果图 vue 注册首页 校验 滑动验证 页面源码
  • mysql explain执行计划

    mysql explain执行计划 mysql gt EXPLAIN SELECT FROM t item i LEFT JOIN t sku s ON i item id s item id LEFT JOIN t sku stock t
  • 楠姐技术漫话:接着唠唠社区发现

    halo 大家好 很开心又和大家见面了 在第一篇技术漫话 图计算的那些事 发布之后 楠姐收到了很多鼓励和支持 非常感谢大家的喜欢 所以楠姐尽自己所能马不停蹄开始第二篇的创作 虽迟但到 也尝试在第二期中 在可读性和观感上尽量做些优化和进步 本
  • Managing Big Data with MySQL学习笔记

    Managing Big Data with MySQL学习笔记 Intro Week 1 How Relational Databases Help Solve Those Problems Database Design Tools E
  • Vue 高德地图实现添加标记,AMap.PlaceSearch 地点搜索,根据页面主题修改地图样式

    Vue 高德地图实现添加标记 AMap PlaceSearch 地点搜索 根据页面主题修改地图样式 效果图 成为开发者并创建key 详细请查阅官方文档 https developer amap com api jsapi v2 guide
  • 分布式锁实现方案3、基于Redis的SET操作实现的分布式锁

    在我的上一篇文章中 关于redis分布式锁的写法 释放锁还有些缺陷 细节见评论部分 本文进一步做了完善 分布式锁实现方案2 基于Redis的SET操作实现的分布式锁 package com alioo common lock import
  • 【leetcode.283】——移动零

    题目 注意 解析 思路 定义left和right指针 都初始化在数组的第一个位置 right指针一直向右走 如果right走到指向的值不为0时 那么right指针指向的值与left指针指向的值进行交换 然后left指针再向后走一步 如此循环
  • c++十大排序——快速排序

    算法基本知识铺垫 有些人可能不知道什么是稳定排序 原地排序 时间复杂度 空间复杂度 我这里先简单解释一下 1 稳定排序 如果 a 原本在 b 的前面 且 a b 排序之后 a 仍然在 b 的前面 则为稳定排序 2 非稳定排序 如果 a 原本
  • nodejs高大上的部署方式-PM2

    如果直接通过node app来启动 如果报错了可能直接停在整个运行 supervisor感觉只是拿来用作开发环境的 再网上找到pm2 目前似乎最常见的线上部署nodejs项目的有forever pm2这两种 使用场合 supervisor是
  • 旋转链表——快慢指针法的实践

    一 题目 给你一个链表的头节点 head 旋转链表 将链表每个节点向右移动 k 个位置 示例1 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL k 2 输出 4 gt 5 gt 1 gt 2 gt 3 gt NULL 解释
  • matlab灵敏度分析操作,灵敏度分析 使用MATLAB编写.doc

    灵敏度分析 使用MATLAB编写 实验二 线性规划的灵敏度分析 实验目的 1 线性规划求解的单纯形法的灵敏度分析的编程实现 2 掌握使用matlab Lingo Excel的规划求解功能求解 并利用 敏感性报告 进行分析 二 实验内容 课本
  • wazuh中的规则编写以及日志分析

    目录 什么是wazuh 如何搭建wazuh 实验环境 wazuh的规则 配置代理 wazuh中的配置了解 ssh的暴力破解 用户自定义规则 SQL注入的检测 什么是wazuh Wazuh是一个免费 开源和企业级的安全监控解决方案 用于威胁检
  • 【2223sW2】LOG2

    写在前面 好好学习 走出宿舍 走向毕设 一些心路历程记录 很少有代码出现 因为鬼知道哪条代码到时候变成毕设的一部分了咧 还是不要给自己的查重挖坑罢了 23 3 2 检验FFT 早上师兄帮忙看了一眼我画的丑图 说样子应该是对的 增加了检查的精
  • D3DXMESHOPT_ATTRSORT

    Mesh的顶点和索引能够被重组以便能更有效的渲染mesh 当我们这样做时 我们说我们优化了一个mesh 我们可以使用下面的方法来进行优化 HRESULT ID3DXMesh OptimizeInplace DWORD Flags CONST
  • DbVisualizer数据库管理工具

    一款数据库管理工具 推荐使用 安装包及破解方法见盘附件 百度云盘 http pan baidu com share link shareid 253466598 uk 1629211176
  • 【Unity3D日常开发】Unity3D中比较string字符串的常用方法

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好 我是佛系工程师 恬静的小魔龙 不定时更新Unity开发技巧 觉得有用记得一键三连哦 一 前言 字符串string的比较有很多方法 比如 E
  • vlc实现PC与树莓派的视频流传输

    目录 一 使用vlc实现PC与树莓派之间的视频流传输 一 Windows 二 树莓派 二 树莓派与Windows系统之间的聊天 三 非堵塞方式传输图像 视频文件 一 使用vlc实现PC与树莓派之间的视频流传输 一 Windows 安装下载v
  • opencv双目视觉标定,激光结构光提取,指定特征点获取世界坐标

    双目视觉标定 激光结构光提取 指定特征点获取世界坐标 标定方面 校正 结构光提取 二维点转换为三维点 总结 这学期在做双目视觉方面的事情 因为没人带 自己一个人踩了很多坑 因此在这写一点自己的总结心得 标定方面 首先标定主要就是为了确定左右