基于PCL的屏幕选点、框选点云、单点选取等c++实现
来源:互联网 发布:java判断date是否相等 编辑:程序博客网 时间:2024/05/19 14:51
1、单点选取程序:
cpp:
#include <pcl/io/pcd_io.h>#include <pcl/point_cloud.h>#include <pcl/point_types.h>#include <pcl/visualization/pcl_visualizer.h>typedef pcl::PointXYZRGBA PointT;typedef pcl::PointCloud<PointT> PointCloudT;// Mutex: //boost::mutex cloud_mutex;struct callback_args{// structure used to pass arguments to the callback functionPointCloudT::Ptr clicked_points_3d;pcl::visualization::PCLVisualizer::Ptr viewerPtr;};voidpp_callback(const pcl::visualization::PointPickingEvent& event, void* args){struct callback_args* data = (struct callback_args *)args;if (event.getPointIndex() == -1)return;PointT current_point;event.getPoint(current_point.x, current_point.y, current_point.z);data->clicked_points_3d->points.push_back(current_point);// Draw clicked points in red:pcl::visualization::PointCloudColorHandlerCustom<PointT> red(data->clicked_points_3d, 255, 0, 0);data->viewerPtr->removePointCloud("clicked_points");data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;}void main(){std::string filename("bunny.pcd");//visualizerpcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("viewer"));if (pcl::io::loadPCDFile(filename, *cloud)){std::cerr << "ERROR: Cannot open file " << filename << "! Aborting..." << std::endl;return;}std::cout << cloud->points.size() << std::endl;//viewer->addPointCloud(cloud, "bunny");cloud_mutex.lock(); // for not overwriting the point cloud// Display pointcloud:viewer->addPointCloud(cloud, "bunny");viewer->setCameraPosition(0, 0, -2, 0, -1, 0, 0);// Add point picking callback to viewer:struct callback_args cb_args;PointCloudT::Ptr clicked_points_3d(new PointCloudT);cb_args.clicked_points_3d = clicked_points_3d;cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(viewer);viewer->registerPointPickingCallback(pp_callback, (void*)&cb_args);std::cout << "Shift+click on three floor points, then press 'Q'..." << std::endl;// Spin until 'Q' is pressed:viewer->spin();std::cout << "done." << std::endl;cloud_mutex.unlock();while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}}
编译运行:
注:使用shift键配合鼠标选点。
2、区域选点
#include <pcl/io/pcd_io.h>#include <pcl/point_cloud.h>#include <pcl/point_types.h>#include <pcl/visualization/pcl_visualizer.h>#include <iostream>#include <vector>pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("viewer"));pcl::PointCloud<pcl::PointXYZ>::Ptr clicked_points_3d(new pcl::PointCloud<pcl::PointXYZ>);int num = 0;void pp_callback(const pcl::visualization::AreaPickingEvent& event, void* args){ std::vector< int > indices; if (event.getPointsIndices(indices)==-1) return; for (int i = 0; i < indices.size(); ++i) { clicked_points_3d->points.push_back(cloud->points.at(indices[i])); } pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(clicked_points_3d, 255, 0, 0); std::stringstream ss; std::string cloudName; ss << num++; ss >> cloudName; cloudName += "_cloudName"; viewer->addPointCloud(clicked_points_3d, red, cloudName); viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, cloudName);}void main(){ if (pcl::io::loadPCDFile("bunny.pcd", *cloud)) { std::cerr << "ERROR: Cannot open file " << std::endl; return; } viewer->addPointCloud(cloud, "bunny"); viewer->setCameraPosition(0, 0, -2, 0, -1, 0, 0); viewer->registerAreaPickingCallback(pp_callback, (void*)&cloud); while (!viewer->wasStopped()) { viewer->spinOnce(100); boost::this_thread::sleep(boost::posix_time::microseconds(100000)); }}
编译运行:
注:使用x键配合鼠标左键选择区域,同时再按下x取消框选。
3、单点选择:
程序中对所以的鼠标点都会罗列在控制台中,和第一个有点差异
cpp:
#include <pcl/io/pcd_io.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/visualization/pcl_visualizer.h> typedef pcl::PointXYZRGBA PointT_XYZ;typedef pcl::PointCloud<PointT_XYZ> PointCloudT_XYZ;// Mutex: // boost::mutex cloud_mutex;struct callback_args{// structure used to pass arguments to the callback function PointCloudT_XYZ::Ptr clicked_points_3d;pcl::visualization::PCLVisualizer::Ptr viewerPtr;};voidpp_callback(const pcl::visualization::PointPickingEvent& event, void* args){struct callback_args* data = (struct callback_args *)args;std::cout << "Picking event active" << std::endl;PointT_XYZ current_point;if (event.getPointIndex() != -1){float x, y, z;event.getPoint(current_point.x, current_point.y, current_point.z);//std::cout << x << ";" << y << ";" << z << std::endl;data->clicked_points_3d->points.push_back(current_point);}// Draw clicked points in red: pcl::visualization::PointCloudColorHandlerCustom<PointT_XYZ> red(data->clicked_points_3d, 255, 0, 0);data->viewerPtr->removePointCloud("clicked_points");data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;}void main(){//visualizer pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("viewer"));pcl::io::loadPCDFile("Bunny.pcd", *cloud);//viewer->addPointCloud(cloud, "bunny"); cloud_mutex.lock(); // for not overwriting the point cloud // Display pointcloud: viewer->addPointCloud(cloud, "bunny");// Add point picking callback to viewer: struct callback_args cb_args;PointCloudT_XYZ::Ptr clicked_points_3d(new PointCloudT_XYZ);cb_args.clicked_points_3d = clicked_points_3d;cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(viewer);viewer->registerPointPickingCallback(pp_callback, (void*)&cb_args);std::cout << "Shift+click on three floor points, then press 'Q'..." << std::endl;// Spin until 'Q' is pressed: viewer->spin();std::cout << "done." << std::endl;cloud_mutex.unlock();while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}}
*4、选点程序,没有标出点,注意,要输入三个数才能进行操作,如1 1 1,按C键可以显示信息
cpp:
#include <pcl/point_cloud.h> #include <pcl/PCLPointCloud2.h> #include <pcl/io/io.h> #include <pcl/io/pcd_io.h> #include <pcl/common/io.h> #include <pcl/io/ply_io.h> #include <pcl/io/vtk_lib_io.h> #include <pcl/visualization/pcl_visualizer.h> using namespace pcl;using namespace std;class pickPoints {public:pickPoints::pickPoints() {viewer.reset(new pcl::visualization::PCLVisualizer("Viewer", true));viewer->registerPointPickingCallback(&pickPoints::pickCallback, *this);}~pickPoints() {}void setInputCloud(PointCloud<PointXYZ>::Ptr cloud){cloudTemp = cloud;}vector<float> getpoints() {return p;}void simpleViewer(){// Visualizer viewer->addPointCloud<pcl::PointXYZ>(cloudTemp, "Cloud");viewer->resetCameraViewpoint("Cloud");viewer->spin();}protected:void pickCallback(const pcl::visualization::PointPickingEvent& event, void*){if (event.getPointIndex() == -1)return;PointXYZ picked_point1, picked_point2;event.getPoints(picked_point1.x, picked_point1.y, picked_point1.z,picked_point2.x, picked_point2.y, picked_point2.z);p.push_back(picked_point1.x); // store points p.push_back(picked_point1.y);p.push_back(picked_point1.z);p.push_back(picked_point2.x);p.push_back(picked_point2.y);p.push_back(picked_point2.z);//cout<<"first selected point: "<<p[0]<<" "<<p[1]<<" "<<p[2]<<endl; //cout<<"second selected point: "<<p[3]<<" "<<p[4]<<" "<<p[5]<<endl; ////pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(p->clicked_points_3d, 255, 0, 0);////data->viewerPtr->removePointCloud("clicked_points");////data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");////data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");////std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;}private:// Point cloud data PointCloud<pcl::PointXYZ>::Ptr cloudTemp;// The visualizer boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;// The picked point vector<float> p;};int main(){//LOAD; PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());pcl::PolygonMesh mesh;pcl::io::loadPCDFile("Bunny.pcd", *cloud);//pcl::fromPCLPointCloud2(mesh.cloud, *cloud);pickPoints pickViewer;pickViewer.setInputCloud(cloud); // A pointer to a cloud pickViewer.simpleViewer();vector<float> pointSelected;pointSelected = pickViewer.getpoints();cout << pointSelected[0] << " " << pointSelected[1] << " " << pointSelected[2] << endl;cout << pointSelected[3] << " " << pointSelected[4] << " " << pointSelected[5] << endl;cin.get();return 0;}
5、整合到Qt+VTK的界面中的技巧:
参看博文
http://blog.csdn.net/hopedengxiwang/article/details/6940719,
http://stackoverflow.com/questions/14267895/error-with-callback-function?answertab=active#tab-top,
http://stackoverflow.com/questions/9596276/how-to-explain-callbacks-in-plain-english-how-are-they-different-from-calling-o:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
如何在类中封装回调函数(第一个链接)
我们知道回调函数只能是全局的或是静态的。
全局函数会破坏类的封装性,故不予采用。
而静态函数只能访问类的静态成员,不能访问类中非静态成员。
那么如何让静态函数访问类的非静态成员呢?
1).声明一静态函数a(),将类实例对象指针做为参数传入。如:
class A()
{
static void a(A *); //静态函数
void b(); //非静态函数
}
void A::a(A * pThis)
{
pThis->b(); //静态函数中调用非静态函数
}
2).回调函数中访问非静态成员
由于回调函数往往有固定定义,并不接受 A * pThis 参数
如:CALLBACK MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
【解决方案1】:本方案当遇到有多个类实例对象时会有问题。原因是pThis指针只能指向一个对象。
class A()
{
static void a(); //静态回调函数
void b(); //非静态函数
static A * pThis; //静态对象指针
}
A * A::pThis=NULL;
A::A() //构造函数中将this指针赋给pThis,使得回调函数能通过pThis指针访问本对象
{
pThis=this;
}
void A::a()
{
if (pThis==NULL) return;
pThis->b(); //回调函数中调用非静态函数
}
【解决方案2】:本方案解决多个类实例对象时方案1的问题。用映射表存所有对象地址,每个对象保存自己的ID号。
typedef CMap<UINT,UINT,A*,A*> CAMap;
class A()
{
static void a(); //静态回调函数
void b(); //非静态函数
int m_ID; //本对象在列表中的ID号
static int m_SID; //静态当前对象ID (需要时,将m_ID赋值给m_SID以起到调用本对象函数的功能)
static CAMap m_Map; //静态对象映射表
}
CAMap A::m_Map;
int A::m_SID=0;
A::A() //构造函数中将this指针赋给pThis,使得回调函数能通过pThis指针访问本对象
{
if(m_Map.IsEmpty())
{
m_ID=1;
}
else
{
m_ID=m_Map.GetCount()+1;
}
m_Map.SetAt( m_ID, this );
}
void A::a()
{
if (m_Map.IsEmpty()) return;
A * pThis=NULL;
if(m_Map.Lookup(m_SID,pThis))
{
pThis->b(); //回调函数中调用非静态函数
};
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
参考下,仔细琢磨一下,可以实现在Qt中的选点功能。
- 基于PCL的屏幕选点、框选点云、单点选取等c++实现
- 选点问题
- 区间选点
- NYOJ891 选点
- 高德地图-地图选点实现
- 贪心——区间选点的算法
- 《PCL点云库学习&VS2010(X64)》Part 10 PCL1.72(VTK6.2.0)选点操作
- 贪心算法-区间选点
- 贪心之区间选点
- 区间选点问题【贪心】
- uva10148Advertisement(区间选点)
- hdu 4883 区间选点
- 区间选点+区间覆盖
- 百度地图 地图选点
- 区间覆盖,选点
- 区间选点问题
- VTK鼠标选点
- uva10148 - Advertisement(区间选点)
- Context
- 重排序,使数组的奇数在偶数前面
- Swift
- Mac下MySQL初始化密码操作
- VMware Centos64位,挂载window共享文件夹
- 基于PCL的屏幕选点、框选点云、单点选取等c++实现
- c++中字符串反转的3种方法<转>
- Swift
- sqlserver 锁以及事务
- Swift
- 模板方法模式
- echart/属性详细介绍
- java多线程Thread类与Runnable 接口使用哪个更好?
- SpringMvc全局异常处理器配置