奥比中光-Astra相机如何用python实现输出RGB彩色图和Depth深度图,并输出三维坐标代码

本文介绍了如何通过Python代码实现对国产奥比中光结构光相机的控制,获取并处理彩色和深度图像。主要步骤包括设置环境、初始化相机、读取帧数据、转换图像格式以及应用色彩映射。同时,文章讨论了深度图像中黑色点的可能原因,并提出了可能的处理方法,如卡尔曼滤波和直方图均衡化。

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

目前项目组在做这个跟结构光相机相关的课题,我在网上调研了几款相机后,最终确定了使用国产奥比中光的相机,主要原因还是性价比高。

下面介绍如何通过python代码实现调用相机的彩色图像和深度图像:

首先你要配备相应的环境:

具有opencv,openni,numpy库

1,首先定义一个鼠标事件,让他能够通过二维像素点的坐标,输出对应的深度坐标:


def mousecallback(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        print(y, x, dpt[y, x])

2,其次就是调用深度相机里面openni2里面的一些配置函数,让其开始:


#创建摄像头对象
cap = cv2.VideoCapture(0)
openni2.initialize()
#设备的型号
dev = openni2.Device.open_any()
#输出设备的型号
print(dev.get_device_info())
#创建深度流的通道
depth_stream = dev.create_depth_stream()
# 彩色和深度图像对齐
dev.set_image_registration_mode(True)  
#开始录制深度图像
depth_stream.start()

3,创建windows窗口,把鼠标事件定义在这个窗口里面:

cv2.namedWindow('depth')
cv2.setMouseCallback('depth', mousecallback)

4.接下来就是循环每一帧图像,以及对每一帧图像进行处理:

    while True:

        frame = depth_stream.read_frame()
        #转换数据格式
        dframe_data = np.array(frame.get_buffer_as_triplet()).reshape([480, 640, 2])
        dpt1 = np.asarray(dframe_data[:, :, 0], dtype='float32')
        dpt2 = np.asarray(dframe_data[:, :, 1], dtype='float32')

        dpt2 *= 255
        #对于为什么要乘于255的解答
        #深度图像的深度值 是按照16位长度(两字节)的数据格式存储的,也可以认为前八位是高字节,后八位是低字节。
        #因此一张深度图像如果是 640480分辨率的话,那么图像字节大小 就是 640480*2,其中一个字节是8位(255)
        dpt = dpt1 + dpt2
        #cv2里面的函数,就是类似于一种筛选
        '假设我们需要让我们的深度摄像头感兴趣的距离范围有差别地显示,那么我们就需要确定一个合适的alpha值,公式为:有效距离*alpha=255,' \
        '假设我们想让深度摄像头8m距离内的深度被显示,>8m的与8m的颜色显示相同,那么alpha=255/(8*10^3)≈0.03,' \
        '假设我们想让深度摄像头6m距离内的深度被显示,>6m的与6m的颜色显示相同,那么alpha=255/(6*10^3)≈0.0425'
        dim_gray = cv2.convertScaleAbs(dpt, alpha=0.17)
        #对深度图像进行一种图像的渲染,目前有11种渲染方式,大家可以逐一去试下
        depth_colormap = cv2.applyColorMap(dim_gray, 2)  # 有0~11种渲染的模式

        cv2.imshow('depth', depth_colormap)

        ret, frame = cap.read()
        cv2.imshow('color', frame)

        key = cv2.waitKey(1)
        if int(key) == ord('q'):
            break

    depth_stream.stop()
    dev.close()

总结下来,完整的代码是:

from openni import openni2
import numpy as np
import cv2


def mousecallback(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        print(y, x, dpt[y, x])


if __name__ == "__main__":
    openni2.initialize()
    dev = openni2.Device.open_any()
    print(dev.get_device_info())
    depth_stream = dev.create_depth_stream()
    dev.set_image_registration_mode(True)
    depth_stream.start()
    cap = cv2.VideoCapture(0)
    cv2.namedWindow('depth')
    cv2.setMouseCallback('depth', mousecallback)
    while True:

        frame = depth_stream.read_frame()
        #转换数据格式
        dframe_data = np.array(frame.get_buffer_as_triplet()).reshape([480, 640, 2])
        dpt1 = np.asarray(dframe_data[:, :, 0], dtype='float32')
        dpt2 = np.asarray(dframe_data[:, :, 1], dtype='float32')

        dpt2 *= 255
        #对于为什么要乘于255的解答
        #深度图像的深度值 是按照16位长度(两字节)的数据格式存储的,也可以认为前八位是高字节,后八位是低字节。
        #因此一张深度图像如果是 640480分辨率的话,那么图像字节大小 就是 640480*2,其中一个字节是8位(255)
        dpt = dpt1 + dpt2
        #cv2里面的函数,就是类似于一种筛选
        '假设我们需要让我们的深度摄像头感兴趣的距离范围有差别地显示,那么我们就需要确定一个合适的alpha值,公式为:有效距离*alpha=255,' \
        '假设我们想让深度摄像头8m距离内的深度被显示,>8m的与8m的颜色显示相同,那么alpha=255/(8*10^3)≈0.03,' \
        '假设我们想让深度摄像头6m距离内的深度被显示,>6m的与6m的颜色显示相同,那么alpha=255/(6*10^3)≈0.0425'
        dim_gray = cv2.convertScaleAbs(dpt, alpha=0.17)
        #对深度图像进行一种图像的渲染,目前有11种渲染方式,大家可以逐一去试下
        depth_colormap = cv2.applyColorMap(dim_gray, 2)  # 有0~11种渲染的模式

        cv2.imshow('depth', depth_colormap)

        ret, frame = cap.read()
        cv2.imshow('color', frame)

        key = cv2.waitKey(1)
        if int(key) == ord('q'):
            break

    depth_stream.stop()
    dev.close()

运行结果是:

 #彩色图像我就不上传了哈

✳至于深度图像上有一些黑色的点点,区域,如果我们点击会显示深度值为0,官方回答没有找到合适的距离,但我经过不断调试,还是有黑色的点点,不知道是什么原因,

✳经过在网上的查找,我发现可以通过:卡勒曼滤波,直方图均衡化,时序数据的均值法这几种方法对深度图像进行处理,后续我如果调试到合适的图像,让其精度达到官方文档说的3mm,之后会将代码发出来。

### 奥比深度相机三维重建方法 #### 使用奥比深度相机进行三维重建的方法概述 对于希望使用奥比深度相机实现三维重建的应用场景,通常涉及以下几个关键技术环节: - **硬件准备**:选用合适的奥比Gemini系列或其他型号的双目3D摄像头作为数据采集设备[^3]。 - **环境搭建**:安装官方提供的SDK以及依赖库,配置开发环境以便能够调用API接口获取图像帧。 - **数据预处理**:通过内参矩阵矫正原始图片中的畸变现象;执行立体匹配算法计算视差图(disparity map),进而转换成距离信息(depth image)[^2]。 - **点云生成**:基于像素坐标系下的深度值构建空间直角坐标系内的三维点集(point cloud data)。可以借助开源工具包如PCL(Point Cloud Library)来简化此过程[^1]。 - **模型优化**:采用滤波器去除噪声干扰项,运用体素化(voxelization)等手段降低冗余度提高效率。 - **可视化展示**:最后一步则是将上述得到的结果渲染出来供用户查看分析。这可能涉及到图形学方面的知识技术栈的选择,比如OpenGL/WebGL框架或是专门用于科学计算可视化的ParaView平台。 #### 示例代码片段 下面给出一段Python代码用来说明如何读取来自奥比传感器的数据创建简单的点云表示形式: ```python import numpy as np from astra_camera import AstraCamera # Assume this is the SDK provided by Orbbec for Python binding. def create_point_cloud(camera:AstraCamera, width=640, height=480): """Create point cloud from depth frame.""" points = [] while True: color_frame, depth_frame = camera.get_frames() # Get synchronized frames if not (color_frame and depth_frame): continue intrinsics = camera.color_intrinsics # Obtain intrinsic parameters of RGB sensor. for v in range(height): for u in range(width): z = depth_frame[v,u]/camera.depth_scale if z==0:continue x = (u-intrinsics.ppx)/intrinsics.fx*z y = (v-intrinsics.ppy)/intrinsics.fy*z rgb = color_frame[v,u][::-1].tolist() points.append([x,y,z]+rgb) break return np.array(points,dtype=np.float32) if __name__=='__main__': cam = AstraCamera() pc_data = create_point_cloud(cam) ```
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值