3d点云,测量网格最短距离

主要的测量方法Dijkstra和Floyd ,geonet。Fast Marching等等

之前还查到热测量

还在苦苦烦恼的我,突然发现vtk官网有类似的实现

 https://kitware.github.io/vtk-examples/site/Cxx/PolyData/DijkstraGraphGeodesicPath/

代码一:只能演示(需要自己改动)

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkDijkstraGraphGeodesicPath.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
int main()
{
	vtkNew<vtkNamedColors> colors;
	vtkNew<vtkSphereSource> sphereSource;
	sphereSource->Update();
	vtkNew<vtkDijkstraGraphGeodesicPath> dijkstra;
	dijkstra->SetInputConnection(sphereSource->GetOutputPort());
	dijkstra->SetStartVertex(0);  //点云开始下标
	dijkstra->SetEndVertex(7);//点云结束下标
	dijkstra->Update();
	vtkNew<vtkPolyDataMapper> pathMapper;
	pathMapper->SetInputConnection(dijkstra->GetOutputPort());

	vtkNew<vtkActor> pathActor;
	pathActor->SetMapper(pathMapper);
	pathActor->GetProperty()->SetColor(colors->GetColor3d("HotPink").GetData());
	pathActor->GetProperty()->SetLineWidth(4);
	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputConnection(sphereSource->GetOutputPort());
	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);
	actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
	vtkNew<vtkRenderer> renderer;
	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	renderWindow->SetWindowName("DijkstraGraphGeodesicPath");

	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderer->AddActor(actor);
	renderer->AddActor(pathActor);
	renderer->SetBackground(colors->GetColor3d("MidnightBlue").GetData());

	auto camera = renderer->GetActiveCamera();
	camera->SetPosition(2.9, -1.6, 0.3);
	camera->SetFocalPoint(0, 0, 0);
	camera->SetViewUp(0, 0, 1);
	camera->SetDistance(3);
	camera->Zoom(1.5);
	renderWindow->Render();

	renderWindowInteractor->Start();

	return 0;
}

代码二:可以实现自己的选点


#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkDijkstraGraphGeodesicPath.h>
#include <vtkCellPicker.h>
#include <vtkIdList.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkDijkstraGraphGeodesicPath.h>
#include <vtkSTLReader.h>
#include <vtkIncrementalOctreePointLocator.h>

class MyInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
	static MyInteractorStyle* New();
	vtkTypeMacro(MyInteractorStyle, vtkInteractorStyleTrackballCamera);

	MyInteractorStyle()
	{
		this->Mesh = nullptr;
		this->Picker = nullptr;
		this->PreId = -1;
		this->CurId = -1;
	}

	~MyInteractorStyle()
	{
		this->Mesh = nullptr;
		this->Picker = nullptr;
		this->PreId = -1;
		this->CurId = -1;
	}

	void OnRightButtonUp()
	{
		auto ren = this->GetDefaultRenderer();
		auto interactor = this->GetInteractor();
		int* clickPos = interactor->GetEventPosition();
		double pos[3];
		this->Picker->Pick(clickPos[0], clickPos[1], 0, ren);
		vtkIdType cellId = this->Picker->GetCellId();
		if (cellId != -1)
		{
			vtkIdType pointId = this->Picker->GetPointId();
			this->CurId = pointId;
			DrawPoint();
			if (this->PreId != -1)
			{
				DrawLine();
			}
			this->PreId = pointId;
		}

		vtkInteractorStyleTrackballCamera::OnRightButtonUp();
	}

	vtkPolyData* Mesh;
	vtkCellPicker* Picker;

private:
	void DrawPoint()
	{
		auto ren = this->GetDefaultRenderer();
		double* pos = this->Mesh->GetPoint(this->CurId);
		auto sphere = vtkSmartPointer<vtkSphereSource>::New();
		sphere->SetRadius(0.01);
		sphere->SetCenter(pos);

		auto pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		pointMapper->SetInputConnection(sphere->GetOutputPort());
		auto pointActor = vtkSmartPointer<vtkActor>::New();
		pointActor->SetMapper(pointMapper);
		pointActor->GetProperty()->SetColor(1, 0, 0); // Red
		ren->AddActor(pointActor);
		ren->Render();
	}

	void DrawLine()
	{
		auto dijkstra = vtkSmartPointer<vtkDijkstraGraphGeodesicPath>::New();
		dijkstra->SetInputData(this->Mesh);
		dijkstra->SetStartVertex(this->PreId);
		dijkstra->SetEndVertex(this->CurId);
		dijkstra->Update();

		vtkIdList* idList = dijkstra->GetIdList();
		auto points = vtkSmartPointer<vtkPoints>::New();
		for (vtkIdType i = 0; i < idList->GetNumberOfIds(); i++)
		{
			vtkIdType id = idList->GetId(i);
			points->InsertNextPoint(this->Mesh->GetPoint(id));
		}
		auto polyLine = vtkSmartPointer<vtkPolyLine>::New();
		polyLine->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints());
		for (vtkIdType i = 0; i < points->GetNumberOfPoints(); i++)
		{
			polyLine->GetPointIds()->SetId(i, i);
		}

		auto cells = vtkSmartPointer<vtkCellArray>::New();
		cells->InsertNextCell(polyLine);

		auto polyData = vtkSmartPointer<vtkPolyData>::New();
		polyData->SetPoints(points);
		polyData->SetLines(cells);

		auto ren = this->GetDefaultRenderer();

		auto lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		lineMapper->SetInputData(polyData);
		//lineMapper->SetInputConnection(dijkstra->GetOutputPort());
		auto lineActor = vtkSmartPointer<vtkActor>::New();
		lineActor->SetMapper(lineMapper);
		lineActor->GetProperty()->SetColor(0, 1, 0); // Green
		lineActor->GetProperty()->SetLineWidth(3);
		ren->AddActor(lineActor);
		ren->Render();
	}

	vtkIdType PreId;
	vtkIdType CurId;
};
vtkStandardNewMacro(MyInteractorStyle);

int main(int argc, char* argv[])
{
	//auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();

	//sphereSource->Update();
	vtkSmartPointer<vtkSTLReader> sphereSource = vtkSmartPointer<vtkSTLReader>::New();
	sphereSource->SetFileName("./Mesh.stl");
//切换自己的stl网格数据,转换我用的软件是CloudCompare
	sphereSource->Update();

	auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(sphereSource->GetOutputPort());
	auto actor = vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);
	actor->GetProperty()->EdgeVisibilityOn();

	auto picker = vtkSmartPointer<vtkCellPicker>::New();
	picker->AddPickList(actor);

	auto renderer = vtkSmartPointer<vtkRenderer>::New();
	auto renderWin = vtkSmartPointer<vtkRenderWindow>::New();
	renderWin->SetSize(600, 600);
	renderWin->AddRenderer(renderer);
	auto style = vtkSmartPointer<MyInteractorStyle>::New();
	style->SetDefaultRenderer(renderer);
	style->Mesh = sphereSource->GetOutput();
	style->Picker = picker;
	auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	interactor->SetRenderWindow(renderWin);
	interactor->SetInteractorStyle(style);

	renderer->AddActor(actor);
	renderer->SetBackground(1, 1, 1);

	interactor->Start();

	return EXIT_SUCCESS;
}

代码三:

主要实现 : 手动输入开始坐标和结束坐标, 并且打印点云坐标,计算距离


#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkDijkstraGraphGeodesicPath.h>
#include <vtkSTLReader.h>
#include <vtkIncrementalOctreePointLocator.h>

int main(int, char* [])
{
	// Read a stl file.
	vtkSmartPointer<vtkPolyData> input1 = vtkSmartPointer<vtkPolyData>::New();
	vtkSmartPointer<vtkSTLReader> reader1 = vtkSmartPointer<vtkSTLReader>::New();
	reader1->SetFileName("./Mesh.stl");
	reader1->Update();
	input1->DeepCopy(reader1->GetOutput());

	input1->DeepCopy(reader1->GetOutput());
	vtkSmartPointer<vtkIncrementalOctreePointLocator> kDTree1 = vtkSmartPointer<vtkIncrementalOctreePointLocator>::New();
	kDTree1->SetDataSet(input1);
	kDTree1->BuildLocator();
	double startPos[3] = { 0.040644, -0.232344, 1.753312 };//开始
	double endPos[3] = { 0.253736, -0.2223910, 1.695677 };//结束
//还是用cc 标注的点

	int startId = kDTree1->FindClosestPoint(startPos);
	int endId = kDTree1->FindClosestPoint(endPos);


	vtkSmartPointer<vtkDijkstraGraphGeodesicPath> dijkstra =
		vtkSmartPointer<vtkDijkstraGraphGeodesicPath>::New();
	dijkstra->SetInputData(reader1->GetOutput());
	dijkstra->SetStartVertex(startId);
	dijkstra->SetEndVertex(endId);
	dijkstra->Update();

	vtkSmartPointer<vtkPolyDataMapper> pathMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	pathMapper->SetInputData(dijkstra->GetOutput());

	vtkSmartPointer<vtkActor> pathActor = vtkSmartPointer<vtkActor>::New();
	pathActor->SetMapper(pathMapper);
	pathActor->GetProperty()->SetColor(1, 0, 0);
	pathActor->GetProperty()->SetLineWidth(4);

	vtkSmartPointer<vtkPolyDataMapper> mapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputData(reader1->GetOutput());

	vtkSmartPointer<vtkActor> actor =
		vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(actor);
	renderer->AddActor(pathActor);
	renderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(640, 480);
	renderWindow->Render();
	renderWindow->SetWindowName("PolyDataGeodesic");

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderWindow->Render();
	renderWindowInteractor->Start();


	vtkSmartPointer<vtkIdList> IdList = vtkSmartPointer<vtkIdList>::New();


	IdList = dijkstra->GetIdList();
	int a[100];
	int b = 0;
	for (int i = 0; i < IdList->GetNumberOfIds(); i++)
	{
		cout << IdList->GetId(i) << endl;
		//cout << IdList[7879];
		a[i] = IdList->GetId(i);
		b += 1;
	}
	vtkPolyData* polydata = reader1->GetOutput();

	double chic = 0;
	for (int i = 0; i < b - 1; i++)
	{
		double p[3];
		cout << a[i];
		polydata->GetPoint(a[i], p);

		std::cout << "Point " << i << " : (" << p[0] << " " << p[1] << " " << p[2]
			<< ")" << std::endl;
		double p1[3];
		polydata->GetPoint(a[i + 1], p1);
		std::cout << "Point " << i << " : (" << p1[0] << " " << p1[1] << " " << p1[2]
			<< ")" << std::endl;
		double squaredDistance = vtkMath::Distance2BetweenPoints(p, p1);

		double distance = std::sqrt(squaredDistance);
		chic += distance;
		std::cout << "Distance = " << distance << std::endl;


	}
	std::cout << "最后 = " << chic << std::endl;




	return EXIT_SUCCESS;
}

打印下标id

 打印点云坐标

计算距离长度(m)

 

 最后把网格的程序拿出来

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>

int  main()
{
    // Load input file into a PointCloud<T> with an appropriate type
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCLPointCloud2 cloud_blob;
    pcl::io::loadPCDFile(".//43.pcd", cloud_blob);
    pcl::fromPCLPointCloud2(cloud_blob, *cloud);
    pcl::VoxelGrid<pcl::PointXYZ> filter;
    filter.setInputCloud(cloud);
    // 设置体素栅格的大小为 1x1x1cm
    filter.setLeafSize(0.01f, 0.01f, 0.01f);
    filter.filter(*cloud);
    //* the data should be available in cloud

    // Normal estimation*
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
    tree->setInputCloud(cloud);
    n.setInputCloud(cloud);
    n.setSearchMethod(tree);
    n.setKSearch(20);
    n.compute(*normals);
    //* normals should not contain the point normals + surface curvatures

    // Concatenate the XYZ and normal fields*
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
    pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
    //* cloud_with_normals = cloud + normals

    // Create search tree*
    pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
    tree2->setInputCloud(cloud_with_normals);

    // Initialize objects
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
    pcl::PolygonMesh triangles;

    // Set the maximum distance between connected points (maximum edge length)
    gp3.setSearchRadius(0.025);

    // Set typical values for the parameters
    gp3.setMu(2.5);
    gp3.setMaximumNearestNeighbors(100);
    gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees
    gp3.setMinimumAngle(M_PI / 18); // 10 degrees
    gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
    gp3.setNormalConsistency(false);

    // Get result
    gp3.setInputCloud(cloud_with_normals);
    gp3.setSearchMethod(tree2);
    gp3.reconstruct(triangles);

    // Additional vertex information
    std::vector<int> parts = gp3.getPartIDs();
    std::vector<int> states = gp3.getPointStates();

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer->setBackgroundColor(0, 0, 0);


    //1的效果
    viewer->addPolygonMesh(triangles, "my");
    //2的效果
    viewer->addPolylineFromPolygonMesh(triangles);


    pcl::io::savePLYFile("result.ply", triangles);
    viewer->addCoordinateSystem(1.0);
    viewer->initCameraParameters();
    while (!viewer->wasStopped()) {
        viewer->spinOnce(100);

    }

    // Finish
    return (0);
}

2的效果

 

1的效果

一起的效果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WangSaLe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值