【OpenCV】ChArUco Marker

1. ChArUco 介绍(Detection of ChArUco Corners)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoihvgFt-1627029583113)(ChArUco.assets/charucodefinition.png)]
Chessboard具有高的交点精度,但是交点提取比较困难。ArUco能够快速检测,但即使使用亚像素精度提取,提取的交点精度也不甚理想。ChArUco集成了Chessboard的高精度与ArUco易用性的优点。

使用ArUco的特征插值出棋盘格黑白块的内角点

2. ChArUco 创建

charuco_board = cv.aruco.CharucoBoard_create(squaresX, squaresY, squareLength, markerLength, dictionary	)

2.1 算子参数

  • squaresX
    X方向棋盘格黑白块的数量
  • squaresY
    Y方向棋盘格黑白块的数量
  • squareLength
    棋盘格黑白块的边长,通常以为单位
  • markerLength
    标志点的边长,单位与参数squareLength的单位相同
  • dictionary
    标志块的编码集合。OpenCV提供了一些内置编码。内置编码命名规则(方便记忆):
    DICT_4X4_50
    • 4X4 两个4分别表示标志块在X与Y方向被划分的数量
    • 50 表示该集合种包含的标志块图案的数量

2.2 参数示意

  • squaresX,squaresY,squareLength,markerLength
    在这里插入图片描述
  • dictionary
    • cv.aruco.DICT_4X4_50 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dv9NRMZx-1627029583117)(ChArUco.assets/image-20210722164648699.png)]
    • cv.aruco.DICT_7X7_50 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8eRjfrnc-1627029583118)(ChArUco.assets/image-20210722164628494.png)]
  • 编码图案的最小模块(以cv.aruco.DICT_4X4_50为例)
    默认情况下编码区域标志块区域有一个模块单位的距离。这个距离可通过draw函数的borderBits参数进行修改。当指定的编码区域为4X4时,实际的标志块区域被6X6等分。边缘有一个模块单位的间距。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hesEE89q-1627029583119)(ChArUco.assets/image-20210722165441929.png)]

2.3 算子返回值

  • charuco_board
    表示一个CharucoBoard对象实例

3. ChArUco 绘制

img	= cv.aruco_CharucoBoard.draw(charuco_board, outSize, marginSize = 1, borderBits = 1)
aruco_CharucoBoard.draw(self, outSize, img=None, marginSize=None, borderBits=None)

3.1 算子参数

  • charuco_board
    CharucoBoard对象实例
  • outSize
    输出图像的像素尺寸,以元组的形式输入,格式(image_width, image_height)
  • marginSize
    >=0
    棋盘格黑白块距离图像边界的最小像素宽度
  • borderBits
    >=1
    标志块种的图案编码区域距离标志块边缘的距离,以编码图案的最小模块为单位

3.2 参数示意

  • marginSize
    • = 1 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I4nqagq6-1627029583119)(ChArUco.assets/image-20210722170111279.png)]
    • = 10 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51miz5ES-1627029583120)(ChArUco.assets/image-20210722170145181.png)]
  • borderBits
    • = 1 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sWcwjNHy-1627029583120)(ChArUco.assets/image-20210722170257623.png)]
    • = 3 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUbJPcQt-1627029583121)(ChArUco.assets/image-20210722170333686.png)]

3.3 算子返回值

  • img
    指定尺寸的二值图像

4. ChArUco 创建与绘制样例

# 如果提示找不到cv2.aruco,请执行以下语句(重装python)
# pip uninstall opencv-python
# pip uninstall opencv-contrib-python
# pip install   opencv-python
# pip install   opencv-contrib-python

import cv2 as cv

dictionary = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_4X4_50)
board=cv.aruco.CharucoBoard_create(7, 7, 0.04, 0.02, dictionary)
img = cv.aruco_CharucoBoard.draw(board, (600, 600), marginSize = 10, borderBits=1)
cv.imwrite('charuco.png',img)

corners, ids, rejectedImgPoints  = cv.aruco.detectMarkers(img, dictionary)
print(corners)
print(ids)
print(rejectedImgPoints)

if(len(ids) > 0):
    cv.aruco.estimatePoseSingleMarkers()

5. ChArUco 标志块检测

当执行ChArUco检测时,首先检测出标志块的角点,每个标志块包含四个角点,按照顺时针顺序排列。

detectMarkers(image, 
              dictionary, 
              corners=None, 
              ids=None, 
              parameters=None, 
              rejectedImgPoints=None, 
              cameraMatrix=None, 
              distCoeff=None)

5.1 算子参数

  • image
    输入图像

  • dictionary
    Charuco的类型

  • corners
    标志块的角点在输入图像坐标系种的坐标。对于每个检测到的标志块会输出四个角点,按照顺时针排列。第一个角点为标志块的左上角点。标志块在corners中的顺序为右下角开始,先从右到左,然后从下到上 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-upRVe0tQ-1627029583121)(ChArUco.assets/image-20210723111306534.png)]- ids
    检测到的标志块的ID,从零开始。第一个标志块位于生成的标定板图像的左上角。从左到右,从上到下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xghoAFqZ-1627029583122)(ChArUco.assets/image-20210723111503397.png)]

  • parameters
    标志块的检测参数

  • rejectedImgPoints
    指示对应位置的标志块的内部编码是不正确的(无法被识别),用于调试目的

  • cameraMatrix
    相机的内参矩阵(float) [ f x 0 c x 0 f y c y 0 0 1 ] \left[ \begin{matrix} &{f_x}&{0}&{c_x}\\&{0}&{f_y}&{c_y}\\&{0}&{0}&{1}\end{matrix} \right] fx000fy0cxcy1

  • distCoeff
    相机的扭曲系数 ( k 1 , k 2 , p 1 , p 2 [ , k 3 [ , k 4 , k 5 , k 6 ] , [ s 1 , s 2 , s 3 , s 4 ] ] ) (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6],[s_1, s_2, s_3, s_4]]) (k1,k2,p1,p2[,k3[,k4,k5,k6],[s1,s2,s3,s4]])

6. ChArUco 标志块绘制

drawDetectedMarkers(image, 
                    corners, 
                    ids=None, 
                    borderColor=None)
  • image

    绘制标志块的图像,必须为1/3通道的图像

  • corners

    相对于输入图像坐标系的标志块角点坐标

  • ids

    标志块的ID

  • borderColor

    标志块绘制的颜色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPqWttah-1627029583122)(ChArUco.assets/image-20210723110150713.png)]

7. ChArUco 棋盘格内角点坐标

棋盘格内角点的坐标是通过标志块角点坐标插值得到。

retval, charucoCorners, charucoIds = interpolateCornersCharuco(markerCorners, 
                                                               markerIds, 
                                                               image, 
                                                               board, 
                                                               cameraMatrix=None, 
                                                               distCoeffs=None, 
                                                               minMarkers=None)
  • markerCorners
    标志块的角点坐标

  • markerIds
    标志块的ID

  • image
    用于角点精定位

  • board
    标定板类型

  • charucoCorners
    输出,棋盘格内角点的坐标

  • charucoIds
    输出,棋盘格内焦点的ID
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dxwhFHFs-1627029583122)(ChArUco.assets/image-20210723112623878.png)]

  • cameraMatrix
    相机内参矩阵

  • distCoeffs
    相机扭曲系数

  • minMarkers
    相邻的标志块被检测出的最小数量

  • retval
    被插值出的内角点数量

8. 标定板位姿估计

retval, rvec, tvec = estimatePoseCharucoBoard(charucoCorners, 
                                              charucoIds, 
                                              board, 
                                              cameraMatrix, 
                                              distCoeffs, 
                                              rvec, 
                                              tvec[, useExtrinsicGuess]) 
```![在这里插入图片描述](https://img-blog.csdnimg.cn/f0f50010e5ba489eab55e468efbadc36.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poeTI5NTYz,size_16,color_FFFFFF,t_70,#pic_center)

9. 源码

import cv2 as cv
import numpy as np

# 创建ChArUco标定板
dictionary = cv.aruco.getPredefinedDictionary(dict=cv.aruco.DICT_6X6_250)
board = cv.aruco.CharucoBoard_create(squaresY=7,
                                     squaresX=5,
                                     squareLength=0.04,
                                     markerLength=0.02,
                                     dictionary=dictionary)
img_board = board.draw(outSize=(600, 500), marginSize=10, borderBits=1)
cv.imwrite(filename='charuco.png', img=img_board, params=None)

camera_matrix = np.array([[532.79536562, 0, 342.4582516],
                          [0, 532.91928338, 233.90060514],
                          [0, 0, 1.]])
dist_coefs = np.array([-2.81086258e-01, 2.72581018e-02, 1.21665908e-03, -1.34204275e-04, 1.58514022e-01])

# 主要用于图形的绘制与显示
img_color = cv.cvtColor(src=img_board,
                        code=cv.COLOR_GRAY2BGR,
                        dstCn=None)

# 查找标志块的左上角点
corners, ids, rejectedImgPoints = cv.aruco.detectMarkers(image=img_board,
                                                         dictionary=dictionary,
                                                         parameters=None,
                                                         cameraMatrix=camera_matrix,
                                                         distCoeff=dist_coefs)
# print(corners)
# print(ids)
if len(ids) > 0:
    print((int(corners[0][0][0][0]), int(corners[0][0][0][1])))
    print((int(corners[1][0][0][0]), int(corners[1][0][0][1])))
    cv.circle(img_color, (int(corners[0][0][0][0]), int(corners[0][0][0][1])), 8, [0, 255, 0])
    cv.circle(img_color, (int(corners[1][0][0][0]), int(corners[1][0][0][1])), 8, [0, 255, 0])
    cv.circle(img_color, (int(corners[2][0][0][0]), int(corners[2][0][0][1])), 8, [0, 255, 0])
    # 绘制标志块的左上角点与对应的ID
    cv.aruco.drawDetectedMarkers(image=img_color, corners=corners, ids=ids, borderColor=None)
    cv.imshow("out", img_color)
    cv.waitKey()

    # 棋盘格黑白块内角点
    retval, charucoCorners, charucoIds = cv.aruco.interpolateCornersCharuco(markerCorners=corners,
                                                                            markerIds=ids,
                                                                            image=img_board,
                                                                            board=board,
                                                                            cameraMatrix=camera_matrix,
                                                                            distCoeffs=dist_coefs)
    print(charucoCorners)
    print(charucoIds)
    if len(charucoIds) > 0:
        # 绘制棋盘格黑白块内角点
        cv.aruco.drawDetectedCornersCharuco(img_color, charucoCorners, charucoIds, [0, 0, 255])
        cv.imshow("out", img_color)
        cv.waitKey()

        rvec = None
        tvec = None
        retval, rvec, tvec = cv.aruco.estimatePoseCharucoBoard(charucoCorners, charucoIds, board, camera_matrix,
                                                               dist_coefs, rvec, tvec)
        if retval:
            cv.aruco.drawAxis(img_color, camera_matrix, dist_coefs, rvec, tvec, 0.01)

cv.imshow("out", img_color)
cv.waitKey()

  • 11
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
【资源介绍】 基于slam技术基础的点云三维重建项目c++源码+操作说明.zip 该项目是个人毕设项目,答辩评审分达到95分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 代码内容 charuco_board(charuco板的创建与识别) calibration(相机标定) segmentation(阈值分割) solvePnP(PnP求解) reconstruction(重建) viz(三维可视化) --- 项目架构 ![image](image/3drecon流程.png) 1. **创建charuco板** 2. **相机标定** 3. **初始化点云** 4. **建立世界坐标系, solvePnP解出相机位姿** 5. **阈值分割提取目标** 6. **重投影筛选出目标三维点** 7. **viz显示三维重建结果** --- 运行环境 ubuntu 18.04 vtk (6.0及以上) pcl (1.8及以上) opencv (3.0及以上) opencv-contrib (opencv同版本) --- 编译项目 在项目根目录下 编译后在build文件夹的bin目录里产生可执行文件 ``` mkdir build cd build cmake .. make ``` --- 运行项目 在项目根目录下 ``` cd build/bin ./recon -w=5 -d=10 -h=7 -sl=34 -ml=20 -c="camera_params.yml" -dp="detector_params.yml" -ci=1 ``` -w charuco板宽的格子数 -h charuco板长的格子数 -d 创建charuco所用的dictionary -sl suqare 长度, 单位mm -ml marker 长度, 单位mm -c 标定得出的相机内参和畸变文件 -dp 识别所用的参数 -ci 调用的摄像头编号 **详细请阅读opencv-contrib aruco中的文档** --- 结果演示

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhy29563

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

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

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

打赏作者

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

抵扣说明:

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

余额充值