图漾深度相机FS-820在Windows上的使用流程
引言
前段时间用过一款图漾的双目深度相机,型号为FS-820,开发工具为Python,这里记录一下在Windows系统上的使用流程,包括一些踩过的坑,给有同样需求的小伙伴们提供一些参考。
1 安装SDK
这部分可以直接参考官网:图漾双目深度相机开发说明文档,里面有详细说明。具体过程如下:
1. 下载Camport3 SDK
方法1:使用浏览器访问 percipioxyz · GitHub 并下载 Camport3 SDK。
方法2:使用 git 指令获取本地副本:打开终端,切换到需存放 SDK 的工作目录下,输入 git clone命令克隆远程仓库:git clone https://github.com/percipioxyz/camport3.git
2. 安装依赖,主要包括CMake和OpenCV
CMake安装参考视频链接:安装CMake
OpenCV安装参考视频链接: 安装OpenCV
另外还需要安装visual studio,用来编译整个工程。这里我安装的是visual studio 2019,具体的安装过程大家可以直接上网去搜,整个安装过程还是需要花点的时间的。
3. 编译SDK
编译步骤如下:
1)在 SDK sample 目录下创建 build 目录;
2)打开 CMAKE GUI;
3)指定源码目录到 sample,编译输出目录为 sample/build;
4) 点击 “Configure”,选择对应的 Visual Studio 版本,下面的平台选择x64,并点击 “Finish”;
5)在 OpenCV_DIR 一栏指定到 opencv/build 文件路径;
6)点击 “Generate”;
7)点击 “Open Project”,打开工程;
8) 编译工程:在 Visual Studio 菜单栏依次点击 “生成” < “生成解决方法” 。
2 生成动态链接库
由于我是用Python来开发的,所以需要生成相应的动态链接库,从而让Python调用。整个工程目录如下图所示:
具体过程如下:
1)修改CMakeLists.txt,指定本地Camport3 SDK路径;
注意:路径分隔符一定要是双斜杠“\\”。
2)在当前目录下创建build目录;
3)打开 CMAKE GUI;
4)指定源码目录到percipio,编译输出目录为 percipio/build;
5)点击 “Configure”,选择对应的 Visual Studio 版本以及x64平台,并点击 “Finish”;
6)在 OpenCV_DIR 一栏指定到 opencv/build 文件路径;
7)点击 “Generate”;
8)点击 “Open Project”,打开工程;
9) 编译工程:在 Visual Studio 菜单栏依次点击 “生成” < “生成解决方法” 。
3 开启相机
将Camport3 SDK中“lib/win/hostapp/x64”路径下的tycam.dll和编译动态链接时在“bulid/Debug”路径下生成的percipio_cam.dll放入python环境中,如下图所示
此时,我们就可以在python脚本中导入动态链接库,并调用相关API。
import platform
from ctypes import *
if platform.system().lower() == 'windows':
lib = cdll.LoadLibrary('percipio_cam.dll')
else:
lib = cdll.LoadLibrary('libpercipio_cam.so')
trigger = c_bool(1) # 1:enable trigger mode
#INIT DEVICE
ret=lib.ty_camera_init(trigger)
print("sdk init ret = %d" % ret)
#GET DEVICE CNT
cnt=lib.ty_cameraGetCnt()
print("percipio device cnt : %d" % cnt)
#GET IMAGE WIDTH AND HEIGHT
color_width = lib.ty_cameraGetRGBImageWidth()
color_height = lib.ty_cameraGetRGBImageHeight()
print("RGB image size :{} {}" .format(color_width, color_height))
depth_width = lib.ty_cameraGetDepthImageWidth()
depth_height = lib.ty_cameraGetDepthImageHeight()
print("Depth image size :{} {}" .format(depth_width, depth_height))
#buffer
RGB_BUFFER_LEN = color_width*color_height*3 # Original RGB
RGB_BUFFER_LEN2 = color_width*color_height*3 # Undistort RGB
DEPTH_BUFFER_LEN = depth_width*depth_height # depth
DEPTH_BUFFER_LEN2 = color_width*color_height # Mapped Depth
DEPTH_BUFFER_LEN3 = color_width*color_height*3 # MappedDepthrendered
P3D_BUFFER_LEN = color_width*color_height*3 # p3dtoColor
#data buffer
data_rgb = (c_ubyte * RGB_BUFFER_LEN)()
data_rgb2 = (c_ubyte * RGB_BUFFER_LEN2)() # Undistort RGB
data_depth = (c_ushort * DEPTH_BUFFER_LEN)() # depth
data_depth2 = (c_ushort * DEPTH_BUFFER_LEN2)() #M appedDepth
data_depthrendered = (c_ubyte * DEPTH_BUFFER_LEN3)() # MappedDepthrendered
data_p3dtoColor=(c_float * P3D_BUFFER_LEN)() # p3dtoColor
FrameIdx=0
while(True):
idx = c_int(0)
lib.ty_camera_RgbExposureTime(500, idx)#range(1,*)
lib.ty_camera_DepthExposureTime(1088, idx)#range(1,1088)
##only output rgb
#lib.ty_camera_SendSoftTrigger()
#lib.ty_camera_fetch_rgb_image(data_rgb, idx)
##only output depth
#lib.ty_camera_SendSoftTrigger()
#lib.ty_camera_fetch_depth_image(data_depth, idx)#only depth
##output Undistort RGB,MappedDepth,MappedDepthrendered,p3dtoColor
lib.ty_camera_SendSoftTrigger()
lib.ty_camera_fetch_all_image(data_rgb2, data_depth2, data_depthrendered, data_p3dtoColor, idx)
offset_center = int(color_width * color_height / 2 + color_width / 2)
# print("RGBD image center info:R {} G {} B {} D {}".format(data_rgb2[3*offset_center + 2], data_rgb2[3*offset_center + 1], data_rgb2[3*offset_center + 0], data_depth2[offset_center]))
print("RGB image center RGBXYZ info:R {} G {} B {} X {} Y {} Z {}".format(data_rgb2[3*offset_center + 2], data_rgb2[3*offset_center + 1], data_rgb2[3*offset_center + 0],data_p3dtoColor[3*offset_center +0], data_p3dtoColor[3*offset_center + 1], data_p3dtoColor[3*offset_center + 2]))
# #for test
# #print("input X pixel")
# #x=int(input())
# #print("X pixel is : %d" % x)
# #print("input Y pixel")
# #y=int(input())
# #print("Y pixel is : %d" % y)
# #offset_center1 = int((y-1)*color_width+x)
# #print("RGB image in pixl {} {} RGBXYZ info:R {} G {} B {} X {} Y {} Z {}".format(x,y,data_rgb2[3*offset_center1 + 2], data_rgb2[3*offset_center1 + 1], data_rgb2[3*offset_center1 + 0],data_p3dtoColor[3*offset_center1 +0], data_p3dtoColor[3*offset_center1 + 1], data_p3dtoColor[3*offset_center1 + 2]))
undistortRGB=np.frombuffer(data_rgb2, dtype=np.uint8)
undistortRGB.shape=(color_height,color_width,3)
cv2.imshow('Undistort RGB',undistortRGB)
# # MappedDepth=np.frombuffer(data_depth2, dtype=np.uint16)
# # MappedDepth.shape=(color_height,color_width)
# # cv2.imshow('Mapped Depth',MappedDepth)
DepthRendered=np.frombuffer(data_depthrendered, dtype=np.uint8)
DepthRendered.shape=(color_height,color_width,3)
cv2.imshow('MappedDepthRendered',DepthRendered)
P3dtoColor=np.frombuffer(data_p3dtoColor, dtype=np.float32)
P3dtoColor.shape=(color_height,color_width,3)
# another way to get RGBXYZ
# print("RGB image center RGBXYZ info:R {} G {} B {} X {} Y {} Z {}".format(data_rgb2[3*offset_center + 2], data_rgb2[3*offset_center + 1], data_rgb2[3*offset_center + 0], P3dtoColor[480][640][0], P3dtoColor[480][640][1], P3dtoColor[480][640][2]))
if cv2.waitKey(1)&0xff==ord('q'):
break
print("fetchframe idx:%d" % FrameIdx)
FrameIdx+=1
cv2.destroyAllWindows()
lib.ty_camera_close()
print("Main done!")
接入相机,等待指示灯闪烁,就可以运行程序啦!