C# winform界面显示3D点云图像(halcon+VTK)

本文介绍了如何通过在VisualStudio中使用NuGet包Activiz和VTK库,将Halcon的3D点云数据展示在C#软件的RenderWindowControl控件上。作者详细阐述了从hv_ObjectModel3D中提取点云信息并转换为VTK兼容格式的过程,以及设置颜色和渲染参数的方法,实现了3D图像的旋转、平移和缩放功能。

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

        前一段时间研究了下halcon里的3d算法,想着把3d图像显示在C#编写的软件界面上,试了下halcon的控件,没成功。后来学习了一点VTK的知识,实现了3d图像的显示,可旋转,平移,缩放观察,当然也能按照自己喜欢的风格进行渲染。

 

具体实现步骤

 在VS里,工具->NuGet包管理器->管理解决方案的NuGet程序包,搜索Activiz  安装上去,工具箱多了个RenderWindowControl控件,这个控件用来显示3d图像的。

我在halcon里处理完点云数据,halcon里的3d模型是hv_ObjectModel3D,在此模型里获取各个点的时候,可以顺带把各个点的渲染参数也加上,获取的点转换的vtk里的数据格式

代码

static vtkPoints h2v_cloud(HTuple hv_ObjectModel3D,out vtkUnsignedCharArray colors_rgb)
        {
            HTuple hv_x = new HTuple();
            HTuple hv_y = new HTuple();
            HTuple hv_z = new HTuple();
            HTuple hv_num = new HTuple();

            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "point_coord_x", out hv_x);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "point_coord_y", out hv_y);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "point_coord_z", out hv_z);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "num_points", out hv_num);

            double x_mid=(hv_x.TupleMax().D+hv_x.TupleMin().D)/2;
            double y_mid=(hv_y.TupleMax().D+hv_y.TupleMin().D)/2;
            double z_mid = (hv_z.TupleMax().D + hv_z.TupleMin().D) / 2;


            int num = hv_num[0].I;
            vtkPoints points = new vtkPoints();

            for (int i = 1; i < num; i++)
            {
                points.InsertPoint(i, hv_x.DArr[i]-x_mid, hv_y.DArr[i]-y_mid, hv_z.DArr[i]-z_mid);
            }

            colors_rgb = vtkUnsignedCharArray.New();
            colors_rgb.SetNumberOfComponents(3);
            double zMax = hv_z.TupleMax().D;
            double zMin = hv_z.TupleMin().D;
            double z=zMax - zMin;
            double z_median = z * 1.0 / 2;
            double r = 0, g = 0, b = 0;
            for(int i = 0; i < num;i++)
            {
                if (hv_z.DArr[i]-zMin>z_median)
                {
                    r = 255 * ((hv_z.DArr[i] - zMin - z_median) / z_median);
                    g= 255 * (1-((hv_z.DArr[i] - zMin - z_median) / z_median));
                    b = 0;
                    colors_rgb.InsertNextTuple3(r, g, b);
                }
                else
                {
                    r = 0;
                    g = 255 * ((hv_z.DArr[i] - zMin - z_median) / z_median);
                    b = 255 * (1 - ((hv_z.DArr[i] - zMin - z_median) / z_median));
                    colors_rgb.InsertNextTuple3(r, g, b);
                }
            }

            return points;
        }

显示在控件上的代码

public void show_cloud(vtkPoints points, vtkUnsignedCharArray colors_rgb, double r = 1.0, double g = 1.0, double b = 1.0, float size = 4f)
        {
            m_points = null;
            m_points = points;

            vtkPolyData polydata = vtkPolyData.New();
            polydata.SetPoints(points);


            //// 设置点云的渲染标量
            polydata.GetPointData().SetScalars(colors_rgb);

            vtkVertexGlyphFilter glyphFilter = vtkVertexGlyphFilter.New();
            glyphFilter.SetInputConnection(polydata.GetProducerPort());

            vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
            mapper.SetInputConnection(glyphFilter.GetOutputPort());


            // 开启颜色渲染
            mapper.ScalarVisibilityOn();

            // 设置渲染范围
            mapper.SetScalarRange(0, 500);


            vtkActor actor = vtkActor.New();
            actor.SetMapper(mapper);
            //actor.GetProperty().SetPointSize(size);
            //actor.GetProperty().SetColor(r, g, b);

            //vtkScalarBarActor scalarBar = vtkScalarBarActor.New();
            //scalarBar.SetLookupTable(mapper.GetLookupTable());
            //scalarBar.SetTitle("Point Cloud");
            //scalarBar.SetHeight(0.7);
            //scalarBar.SetWidth(0.1);
            //scalarBar.SetNumberOfLabels(10);
            //scalarBar.GetLabelTextProperty().SetFontSize(4);
            vtkRenderer render = renderWindowControl1.RenderWindow.GetRenderers().GetFirstRenderer();

            //// 清空点云
            for (int i = 0; i < render.GetActors().GetNumberOfItems(); i++)
            {
                var item = render.GetActors().GetItemAsObject(i);
                render.RemoveActor((vtkActor)item);
                item.Dispose();
            }

            render.AddActor(actor);
            //render.AddActor(scalarBar);
            render.SetViewport(0.0, 0.0, 1, 1);
            render.ResetCamera();
            this.Refresh();
        }

 

 

### 关于C#中的点云处理 在C#环境中,点云的处理主要依赖外部库的支持。以下是几种常见的实现方式及其特点: #### 使用PCLSharp进行点云处理和可视化 PCLSharp 是一个用于封装 PCL(Point Cloud Library)功能的 .NET 库[^3]。通过该库可以在 WinForm 或 WPF 中轻松实现点云数据的操作与可视化。其核心优势在于能够调用底层 C++ 实现的功能,从而提供高效的计算能力。 以下是一个简单的代码示例,展示了如何利用 `PCLSharp` 加载并显示点云文件: ```csharp using System; using System.Windows.Forms; using PCLSharp; private void LoadAndShowPointCloud() { // 创建一个新的点云集对象 var cloud = new PointCloud<PointXYZ>(); // 使用PCDReader读取点云文件 using (var reader = new PCDReader()) reader.Read(@"path_to_your_pcd_file.pcd", cloud); // 显示点云到指定窗口控件中 ShowPointCloud(cloud, renderWindowControl); } ``` 此方法适用于需要高性能点云运算的应用场景,并且支持多种点云算法,如滤波、分割以及特征提取等。 --- #### 结合 Activiz 进行点云可视化 ActivizVTKC# 封装版本,提供了强大的三维图形渲染能力。对于希望快速构建点云可视化的开发者来说,这是一个不错的选择[^4]。然而需要注意的是,相比专门针对点云优化的 PCLSharp,Activiz 更侧重通用性的三维模型展示,在特定领域可能稍显不足。 下面是一段使用 Activiz 展示点云的例子: ```csharp using ActiViz.NET; public void VisualizePointCloud(string filePath) { vtkPolyDataReader reader = new vtkPolyDataReader(); reader.SetFileName(filePath); reader.Update(); vtkRenderer renderer = RenderWindow.Renderers[0]; vtkActor actor = new vtkActor(); actor.Mapper = new vtkPolyDataMapper(); ((vtkPolyDataMapper)actor.Mapper).SetInputConnection(reader.GetOutputPort()); renderer.AddActor(actor); RenderWindow.Render(); } ``` 上述代码片段说明了如何借助 Activiz 来加载 `.vtp` 文件格式的数据源,并将其呈现在 GUI 上。 --- #### HalconC# 联动开发 Halcon 提供了一套完整的机器视觉解决方案,其中包括对三维点云的支持。虽然它的学习曲线较陡峭,但对于工业应用而言非常可靠。如果项目需求涉及到复杂的图像分析或者高精度测量,则可以考虑引入 Halcon SDK 并配合 C# 编程完成任务。 典型的工作流如下所示: 1. 利用 Halcon API 获取原始传感器采集得到的深度图; 2. 对获取的结果执行必要的预处理步骤; 3. 最终将转换后的点云传递给前端界面组件呈现出来。 --- ### 总结 综上所述,目前存在多条路径可满足 C#点云处理的需求。具体选择取决于实际应用场景和技术栈偏好等因素。例如追求极致性能可以选择基于 PCLSharp 构建;而倾向于易用性和灵活性则推荐尝试 Activiz 方案;另外还有 HALCON 集成选项可供参考。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值