代码参考其他博客,并对其简单更改:
https://www.cnblogs.com/lidabo/p/3437587.html
https://www.jianshu.com/p/cbc6b3635844
鼠标点击处的点云坐标保存
//*****************************************************************************************************
// 获得单帧点云中的角反射器角点
//
// 按中shift键,然后在角点处鼠标左击
// source devel/setup.bash && rosrun cam_laser_calib pcd_points_get 111.pcd
// pcl_viewer 111.pcd
//**************************************************************************************************
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
using PointT = pcl::PointXYZRGB;
using PointCloudT = pcl::PointCloud<PointT>;
// 用于将参数传递给回调函数的结构体
struct CallbackArgs {
PointCloudT::Ptr clicked_points_3d;
pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};
void pickPointCallback(const pcl::visualization::PointPickingEvent &event, void *args) {
CallbackArgs *data = (CallbackArgs *) 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);
// 绘制红色点
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;
FILE *fpWrite=fopen("lidar_xyz.txt","a");
fprintf(fpWrite,"%1.4f %1.4f %1.4f\n",current_point.x,current_point.y,current_point.z);
fclose(fpWrite);
}
int main(int argc, char *argv[]) {
std::string b = argv[1];
std::cout<<"打开pcd点云文件:"<<b<<'\n';
std::string file_name(b);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("viewer"));
// 加载点云
if (pcl::io::loadPCDFile(file_name, *cloud) == -1) {
std::cerr << "could not load file: " << file_name << std::endl;
}
std::cout << cloud->points.size() << std::endl;
// 显示点云
viewer->addPointCloud(cloud, "cloud");
viewer->setCameraPosition(0, 0, -2, 0, -1, 0, 0);
// 添加点拾取回调函数
CallbackArgs 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(pickPointCallback, (void*)&cb_args);
std::cout << "Shift+click on three floor points, then press 'Q'..." << std::endl;
viewer->spin();
std::cout << "done." << std::endl;
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
return 0;
}
鼠标点击处的像素坐标保存
//********************************************************************
//
// source devel/setup.bash && rosrun cam_laser_calib image_get image.png
//
//*********************************************************************
#include<iostream>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<fstream>
#include<string>
using namespace cv;
using namespace std;
cv::Mat image1;
void onMouse(int event, int x, int y, int flags, void* param) //evnet:鼠标事件类型 x,y:鼠标坐标 flags:鼠标哪个键
{
Mat* im = reinterpret_cast<Mat*>(param);
switch (event) {
case EVENT_LBUTTONDOWN:
//显示图像像素值
FILE *fpWrite=fopen("image_get.txt","a");
fprintf(fpWrite,"%d %d\n",x,y);
fclose(fpWrite);
Point point;
point.x=x;
point.y=y;
circle(image1,point,2,Scalar(0,0,255),-1);
imshow("image1",image1); //显示图像;
if (static_cast<int>(im->channels()) == 1)
{
//若图像为灰度图像,则显示鼠标点击的坐标以及灰度值
cout << "at (" << x << ", " << y << " ) value is: " << static_cast<int>(im->at<uchar>(Point(x, y))) << endl;
}
else
{
//若图像为彩色图像,则显示鼠标点击坐标以及对应的B, G, R值
cout << "at (" << x << ", " << y << ")"
<< " B value is: " << static_cast<int>(im->at<Vec3b>(Point(x, y))[0])
<< " G value is: " << static_cast<int>(im->at<Vec3b>(Point(x, y))[1])
<< " R value is: " << static_cast<int>(im->at<Vec3b>(Point(x, y))[2])
<< endl;
}
break;
}
}
int main(int argc,char** argv)
{
string image_name= argv[1];
image1 = imread(image_name); //读取图像;
if (image1.empty())
{
cout << "读取错误" << endl;
return -1;
}
imshow("image1",image1); //显示图像;
setMouseCallback("image1", onMouse, reinterpret_cast<void*>(&image1)); //关联图像显示窗口和onMouse函数
waitKey(0); //暂停,保持图像显示,等待按键结束
return 0;
}