前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于点云的视觉引导系统-方案解读.1

基于点云的视觉引导系统-方案解读.1

作者头像
云深无际
发布2022-04-15 08:34:18
5820
发布2022-04-15 08:34:18
举报
文章被收录于专栏:云深之无迹

去年由奥比中光赞助的3D创新视觉赛落下帷幕,留下了令人印象深刻地一些作品(惭愧,虽然我也参加了,但是算法上面有些地方做地不好,就没有参与到后续地评奖中,希望今年获奖,哈哈哈哈哈),另外今年也幸运的当了社区的版主>.<,欢迎大家来投稿!

代码语言:javascript
复制
https://developer.orbbec.com.cn/forum.html

不过我发现论坛在长久的运营过程中其实留下了很多资料,但是缺乏系统的整理,所以我就准备整理一份开源的立体视觉资料出来,这里也希望大家给一些相关的建议。

在正式整理之前,我发现两届比赛出现了不少有用的方案,所以准备做一个系列的方案解读。一方面是为了好的方案继续发挥作用,二是为了他人的项目参考。

已完结~

那为什么会选定这样一个方案来解读呢?以下给出一封感兴趣的读者发来的邮件:

关键信息打码了

可以看出,这个项目是完整的,以及有了实用性,其次是老师想选用这个案例用于教学和指导学生实践学习。

我的文章并不简明,内部大量充斥着口语,个人想法,其看起来更像是一份工作札记,但是文风这种东西改起来不是很容易,希望读者理解。

项目缘起:

大哥在展会上面看到了这个东西

运行起来的样子

So~就自己做一个!

功能目标:基于点云的轨迹引导,即无论待引导物体以何种位姿摆放(要求该位姿在机械臂的行程范围内),视觉系统均能定位到该物体,并引导机械臂按需要的轨迹实现一定的工艺流程。

应用场景:需要轨迹引导的工业现场。

其实有人会问,那这个东西传统的二维视觉做不了吗?事实上是可以,但是它不太能满足自由度多时机器人的引导,而加入了Depth会增加这种精度。

demo的样子,kuka机器手臂一直在沿着鞋底的边缘划线

系统的硬件为相机,处理,执行器

安装的位置如图所示,右侧的相机对工作平面进行解算,求出解算边缘,而后给机械臂(这部分作者没有写,而且将处理数据输入给机械臂的示教器)

奥比中光的Zora P1开发板:板子上跑的是armbian操作系统,部署的是点云采集和点云匹配程序,点云采集采用C++编写,基于奥比中光官方提供的OpenNI2 SDK。

代码语言:javascript
复制
https://developer-orbbec-oss.oss-cn-shenzhen.
aliyuncs.com
/2021-05-26/public1/images/gather/deveban.jpg

这里是P1开发板的图床位置,可以看到是阿里云的OBS,不知道买的啥套餐

板子一角

还是很丰富的接口

板子上面使用的armbian,就是基于Debiana适配的ARM开发板~

什么是Armbian?

Armbian是其他项目可以信赖的单板计算机(SBC)的基本操作系统平台。

  • 轻量级基于Debian或Ubuntu的Linux发行版,专门用于ARM开发板
  • 每个系统均由Armbian Build Tools进行编译,组装和优化
  • 它具有强大的构建和软件开发工具,可以进行自定义构建
  • 充满活力的社区

其实就是一套完整的Linux系统,但是工具链齐全~文档丰富

有着完整的文档

就是使用的这个相机

然后就是精度真的困难是不够用

在P1上面使用的是Armbian的系统,论坛里面有详细的这个安装的教程,我这里也没有机器,我就不去做了,不过我觉得是jetson或者是树莓派都可以去部署。

香橙派Armbian系统安装之认识

香橙派Armbian系统安装之烧录

现在应该写标定的东西,但是写采集的也OK,为了流程一致,写标定。

相机标定是视觉系统的基础,工业级的相机标定需要碳纤维(或者玻璃等)的工业级标定板,保证平整度和角点精度。同时需要遮住激光器,并使用红外光源,使得红外相机能采集到清晰的标定板图像。

但是,普通开发者通常不具备上述条件,面临的情况常常是没有标定板和红外光源。为此,项目使用自制标定板,即通过代码生成高分辨率的棋盘格图像,并用打印机将其打印出来,贴在平板上。但是由于没有红外光源,红外相机只能借助带激光散斑的激光器的光源来拍摄标定板图像,带来的问题是部分角点检测的误差较大。为了解决这个问题,项目采用先执行一次相机标定,保留重投影误差小的70%的点,再执行一次相机标定。这么做可以明显降低重投影误差、提高精度,使用此方法标定出的相机内外参通过深度图和彩色图的对齐来验证,确实取得了良好的效果。

为什么这个标定过程要做这么多的工作?其实我们要知道一点,我们的计算理论都是完美无瑕的,光线很直,镜头没有各种光学误差,CCD和镜头的装配也是没有误差。

但事实上,一切都“比较糟糕”,所以相机的设计处处都是对现实的妥协,幸好,我们可以将这些误差算出来,做计算方法上面的补偿。

现在用的比较多的是张正友博士的棋盘格标定法(hhhh,大佬也姓张)

也叫标定板

好,我们自己写程序实现这个标定板的生成。

这里准备了C++和Python的版本

原版是C++的,但是改写成Python的。

首先引入库,注意OpenCV的安装。后面三个参数是单个标定快的大小以及标定块的数量。

板子单位格子的高和宽

参数计算,不符合就报错

我们的图像应该有一个容器来放它们:

代码语言:javascript
复制
cv::Mat image(resolution, CV_8UC1, cv::Scalar::all(255));

搞个容器,初始化一下。后面参数Scalar 是个short型vector。指定这个能够使用指定的定制化值来初始化矩阵。

代码语言:javascript
复制
CV_
[The number of bits per item]
[Signed or Unsigned]
[Type Prefix]C[The channel number]

这是这个函数的签名。

这是核心部分(吓死我,都不敢说是算法)。

这个填充是一开始都是黑色的,一个黑色的页面,纵向的逐像素的扫描。

像素点的操作。

显示+保存,CPP看累了吗?可以看看Python~

SCALE是缩放的系数,可以控制大小,都使用元组防止篡改。

逻辑和CPP的一样,这一段

生成一张全白的照片,我上面写错了

两个步骤,先扫描纸面,然后按照逻辑填充黑点。

完事~

代码语言:javascript
复制
import cv2
import numpy as np
import sys

# 参数
SCALE = 0.48  # 0.4 便于按比例整体缩放图片
perBoardPixel = int(100 * SCALE * 2)  # 每个黑白格的像素数
boardSize = (7, 10)  # (height, width) 棋盘格的大小
resolution = (int(1400 * SCALE), int(2000 * SCALE))  # (height, width) 图片大小

if __name__ == "__main__":

    basisHeight = (resolution[0] - perBoardPixel * boardSize[0]) // 2
    basisWidth = (resolution[1] - perBoardPixel * boardSize[1]) // 2
    if basisHeight < 0 or basisWidth < 0:
        print("Resolution doesn't match!")
        sys.exit(0)

    image = np.ones(resolution).astype(np.uint8) * 255  # 全白的图片
    flag = 0


    for j in range(0, boardSize[0]):
        for i in range(0, boardSize[1]):

            flag = (i + j) % 2
            
            if flag == 0:
                for n in range(j * perBoardPixel, (j + 1) * perBoardPixel):
                    for m in range(i * perBoardPixel, (i + 1) * perBoardPixel):
                        image[n + basisWidth, m + basisHeight] = 0  # 赋黑色

    cv2.imshow("chessBoard", image)
    cv2.waitKey(0)
    cv2.imwrite("chessBoard.bmp", image)

设置参数,直接运行。

代码语言:javascript
复制
https://github.com/appliedengdesign/vscode-gcode-syntax

原作者链接

代码语言:javascript
复制
https://blog.csdn.net/dawudayudaxue/article/details/106339491

标定算法

代码语言:javascript
复制
https://developer.orbbec.com.cn/forum_plate_module_details.html?id=830

论坛的位置

代码语言:javascript
复制
https://github.com/3DCVdeveloper/Visual-guided-manipulator

可能出于一些别的保护原因,这个方案的源码和相关资料没有全部在Github上面上传,不过学习起来还是绰绰有余,如果有其它疑问,可以联系小助手获取。

代码语言:javascript
复制
https://docs.armbian.com/User-Guide_Basic-Troubleshooting/

Armbian文档位置

代码语言:javascript
复制
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/core/mat%20-%20the%20basic%20image%20container/mat%20-%20the%20basic%20image%20container.html
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是Armbian?
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档