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

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

下面介绍如何通过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()

运行结果是:

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

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

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

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

你可能感兴趣的:(Opencv图像处理,1024程序员节)