3D相机点云滤波
写在前面
- 本人从事机器视觉细分的3D相机行业。编写此系列文章主要目的有:
- 1、便利他人应用3D相机,本系列文章包含公司所出售相机的SDK的使用例程及详细注释;
- 2、促进行业发展及交流。
- 知微传感Dkam系列3D相机可以应用于定位分拣、焊接焊缝提取、逆向建模、检测测量等领域
点云滤波及API说明
点云滤波说明
- 知微传感为其3D相机输出的点云准备了滤波API,用于噪声或离群点的滤除
- 点云滤波功能在上位机完成
- 被滤除的点位置保留,指标值为0
- 滤波API在获取点云后使用
相关API
- FilterPointCloudCSharp 点云滤波
void FilterPointCloudCSharp(Camera_Object_C* camera_obj,PhotoInfoCSharp &raw_data_info, char *xyz, int pixel_size, double level)
- 函数功能: 滤波
- 参 数: camera_obj:相机的结构体指针;raw_data_info:采集的点云数据;xyz:像素点;pixel_size:像素大小;level:滤波的等级 (取值范围大于 0//等于 0 所有的点云都被过滤//趋于 0 滤波效果越明显)
- 返回值: 无
- 原理:统计滤波
- SpatialFilterPointcloudCSharp 空间滤波
int SpatialFilterPointcloudCSharp(Camera_Object_C* camera_obj, PhotoInfoCSharp &raw_data_info, char *xyz, int pixel_size, int Area_PointCloudCount)
- 函数功能:空间滤波
- 参数:camera_obj:相机的结构体指针;raw_data:获取的点云数据;xyz:像素点;pixel_size:像素大小;Area_PointCloudCount:滤波范围 (取值范围大于0//等于0滤波不起作用//取值越大于0效果越明显,取值范围:0~99)
- 返回值:0,成功;非0,失败
- 原理:将输入的点云分成30×30×30个空间,空间内有效点的数量少于给定值时,将该空间内多有点滤除(实际将点的坐标值赋值为0),处理后的点仍存放在raw_data中
例程及注释
- 本例程基于WIN10+VisualStudio2022+DkamSDK_1.6.83
- DkamSDK的配置方法请参考SDK说明书
- 本例程在D330XS型相机上验证
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace filter
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello ZhiSENSOR!");
//**********************************************查询、连接相机****************************************************
int camer_num = 0;
int camera_ret = -1;
//想要连接的相机IP
String tarCameraIP = "192.168.40.91";
//发现局域网内的相机
camer_num = DkamSDK_CSharp.DiscoverCamera();
Console.WriteLine("局域网内共有" + camer_num + "台3D相机");
//显示局域网内相机IP
for (int i = 0; i < camer_num; i++)
{
Console.WriteLine("局域网内相机的IP为:" + DkamSDK_CSharp.CameraIP(i));
if (String.Compare(DkamSDK_CSharp.CameraIP(i), tarCameraIP) == 0)
{
camera_ret = i;
}
}
Console.WriteLine("连接IP为:" + tarCameraIP + "的相机");
//连接相机
SWIGTYPE_p_CAMERA_OBJECT camera = DkamSDK_CSharp.CreateCamera(camera_ret);
int connect = DkamSDK_CSharp.CameraConnect(camera);
if (connect == 0)
{
Console.WriteLine("相机连接成功!");
//获取当前红外相机的宽和高
SWIGTYPE_p_int width_gray = DkamSDK_CSharp.new_intArray(0);
DkamSDK_CSharp.GetCameraWidth(camera, width_gray, 0);
int width = DkamSDK_CSharp.intArray_getitem(width_gray, 0);
SWIGTYPE_p_int height_gray = DkamSDK_CSharp.new_intArray(0);
DkamSDK_CSharp.GetCameraHeight(camera, height_gray, 0);
int height = DkamSDK_CSharp.intArray_getitem(height_gray, 0);
Console.WriteLine("红外图宽度:" + width + " 红外图高度:" + height);
//**********************************************采集点云数据****************************************************
//定义点云大小
PhotoInfoCSharp PointCloud_data = new PhotoInfoCSharp();
int pointsize = width * height * 6;
byte[] point_pixel = new byte[pointsize];
//开启数据流通道(0:红外 1:点云 2:RGB)
//点云
int streampoint = DkamSDK_CSharp.StreamOn(camera, 1);
if (streampoint == 0)
{
Console.WriteLine("点云通道打开成功!");
}
else
{
Console.WriteLine("点云通道打开失败!!! 错误码:" + streampoint);
}
//开始接受数据
int start = DkamSDK_CSharp.AcquisitionStart(camera);
if (start == 0)
{
Console.WriteLine("可以开始接收数据!");
}
else
{
Console.WriteLine("不能接收数据!!! 错误码:" + start);
}
//刷新缓冲区
DkamSDK_CSharp.FlushBuffer(camera, 1);
Console.WriteLine("等待数据采集、传输。。。");
//获取点云数据
int capturepoint = DkamSDK_CSharp.TimeoutCaptureCSharp(camera, 1, PointCloud_data, point_pixel, pointsize, 10000000);
if (capturepoint == 0)
{
Console.WriteLine("点云数据接收成功!");
}
else
{
Console.WriteLine("点云数据接收失败!!! 错误码:" + capturepoint);
}
Console.WriteLine();
//保存点云数据
int savepoint = DkamSDK_CSharp.SavePointCloudToPcdCSharp(camera, PointCloud_data, point_pixel, pointsize, "pointcloud.pcd");
if (savepoint == 0)
{
Console.WriteLine("原始点云数据保存成功!");
}
else
{
Console.WriteLine("原始点云数据保存失败!!! 错误码:" + savepoint);
}
//*********************************************滤波****************************************************
//滤波
DkamSDK_CSharp.FilterPointCloudCSharp(camera, PointCloud_data, point_pixel, pointsize, 1);
//保存滤波后点云数据
savepoint = DkamSDK_CSharp.SavePointCloudToPcdCSharp(camera, PointCloud_data, point_pixel, pointsize, "pointcloud_Filter.pcd");
if (savepoint == 0)
{
Console.WriteLine("滤波点云数据保存成功!");
}
else
{
Console.WriteLine("滤波点云数据保存失败!!! 错误码:" + savepoint);
}
//*********************************************空间滤波****************************************************
//空间滤波
int spfilter = DkamSDK_CSharp.SpatialFilterPointcloudCSharp(camera, PointCloud_data, point_pixel, pointsize, 80);
if (spfilter == 0)
{
Console.WriteLine("空间滤波成功!");
}
else {
Console.WriteLine("空间滤波失败!!! 错误码:" + savepoint);
}
//保存滤波后点云数据
savepoint = DkamSDK_CSharp.SavePointCloudToPcdCSharp(camera, PointCloud_data, point_pixel, pointsize, "pointcloud_SpatialFilter.pcd");
if (savepoint == 0)
{
Console.WriteLine("空间滤波点云数据保存成功!");
}
else
{
Console.WriteLine("空间滤波点云数据保存失败!!! 错误码:" + savepoint);
}
//断开相机连接
int disconnect = DkamSDK_CSharp.CameraDisconnect(camera);
if (disconnect == 0)
{
Console.WriteLine("成功断开相机!");
}
else
{
Console.WriteLine("断开相机失败!!! 错误码:" + disconnect);
}
//销毁相机参数
DkamSDK_CSharp.DestroyCamera(camera);
}//connect = 0
else
{
Console.WriteLine("相机连接失败,失败代码:" + connect);
}
}//MAIN
}//PROGRAM
}//NAMESPACE
运行结果

结果对比
-
滤波前
-
滤波后
-
滤波+空间滤波后
-
对比可知,滤波功能可以有效滤除噪点或离群点
后记
- 知微传感Dkam系列3D相机可以应用于定位分拣、焊接引导、逆向建模、检测测量等领域