我正在使用PCL来创建一个应用程序,用于查看Openni Grabber中注册的深度云以及带有一些按钮的面板以获得一些附加功能。我发现QVTK可以帮助达到这个目的。我试过这个basic implementation。它工作正常。我使用这种方法来修改openni_viewer示例以在Qt窗口中进行可视化。但是我得到了段错误。我真的很感激任何帮助。
template <typename PointType>
class OpenNIViewer
{
public:
typedef pcl::PointCloud<PointType> Cloud;
typedef typename Cloud::ConstPtr CloudConstPtr;
OpenNIViewer (pcl::Grabber& grabber, int argc, char** argv)
: cloud_viewer_ (new pcl::visualization::PCLVisualizer ("PCL OpenNI cloud", false))
, grabber_ (grabber)
, rgb_data_ (0), rgb_data_size_ (0), cloud_init(false), argc(argc), argv(argv)
{
}
void
cloud_callback (const CloudConstPtr& cloud)
{
FPS_CALC ("cloud callback");
boost::mutex::scoped_lock lock (cloud_mutex_);
cloud_ = cloud;
if (cloud)
{
FPS_CALC ("drawing cloud");
if (!cloud_init)
{
cloud_viewer_->setPosition (0, 0);
cloud_viewer_->setSize (cloud->width, cloud->height);
cloud_init = !cloud_init;
}
if (!cloud_viewer_->updatePointCloud (cloud, "OpenNICloud"))
{
cloud_viewer_->addPointCloud (cloud, "OpenNICloud");
cloud_viewer_->resetCameraViewpoint ("OpenNICloud");
}
}
}
void
keyboard_callback (const pcl::visualization::KeyboardEvent& event, void*)
{
if (event.getKeyCode ())
cout << "the key \'" << event.getKeyCode() << "\' (" << event.getKeyCode() << ") was";
else
cout << "the special key \'" << event.getKeySym() << "\' was";
if (event.keyDown())
cout << " pressed" << endl;
else
cout << " released" << endl;
}
void
mouse_callback (const pcl::visualization::MouseEvent& mouse_event, void*)
{
if (mouse_event.getType() == pcl::visualization::MouseEvent::MouseButtonPress && mouse_event.getButton() == pcl::visualization::MouseEvent::LeftButton)
{
cout << "left button pressed @ " << mouse_event.getX () << " , " << mouse_event.getY () << endl;
}
}
/**
* @brief starts the main loop
*/
void
run ()
{
cloud_viewer_->registerMouseCallback (&OpenNIViewer::mouse_callback, *this);
cloud_viewer_->registerKeyboardCallback(&OpenNIViewer::keyboard_callback, *this);
boost::function<void (const CloudConstPtr&) > cloud_cb = boost::bind (&OpenNIViewer::cloud_callback, this, _1);
boost::signals2::connection cloud_connection = grabber_.registerCallback (cloud_cb);
grabber_.start ();
QApplication app(argc, argv);
QMainWindow* window = new QMainWindow;
window->resize(640,480);
QHBoxLayout *layout = new QHBoxLayout;
QVTKWidget widget1;
widget1.resize(640, 480);
layout->addWidget(&widget1);
vtkSmartPointer<vtkRenderWindow> renderWindow = cloud_viewer_->getRenderWindow();
widget1.SetRenderWindow(renderWindow);
QWidget* center = new QWidget();
window->setCentralWidget(center);
window->centralWidget()->setLayout(layout);
window->show();
app.exec();
grabber_.stop ();
cloud_connection.disconnect ();
if (rgb_data_)
delete[] rgb_data_;
}
boost::shared_ptr<pcl::visualization::PCLVisualizer> cloud_viewer_;
pcl::Grabber& grabber_;
boost::mutex cloud_mutex_;
CloudConstPtr cloud_;
unsigned char* rgb_data_;
unsigned rgb_data_size_;
bool cloud_init;
int argc;
char** argv;
};
boost::shared_ptr<pcl::visualization::PCLVisualizer> cld;
boost::shared_ptr<pcl::visualization::ImageViewer> img;
int
main (int argc, char** argv)
{
XInitThreads();
std::string device_id("");
pcl::OpenNIGrabber::Mode depth_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;
pcl::OpenNIGrabber::Mode image_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;
bool xyz = false;
if (argc >= 2)
{
device_id = argv[1];
if (device_id == "--help" || device_id == "-h")
{
printHelp(argc, argv);
return 0;
}
else if (device_id == "-l")
{
if (argc >= 3)
{
pcl::OpenNIGrabber grabber(argv[2]);
boost::shared_ptr<openni_wrapper::OpenNIDevice> device = grabber.getDevice();
cout << "Supported depth modes for device: " << device->getVendorName() << " , " << device->getProductName() << endl;
std::vector<std::pair<int, XnMapOutputMode > > modes = grabber.getAvailableDepthModes();
for (std::vector<std::pair<int, XnMapOutputMode > >::const_iterator it = modes.begin(); it != modes.end(); ++it)
{
cout << it->first << " = " << it->second.nXRes << " x " << it->second.nYRes << " @ " << it->second.nFPS << endl;
}
if (device->hasImageStream ())
{
cout << endl << "Supported image modes for device: " << device->getVendorName() << " , " << device->getProductName() << endl;
modes = grabber.getAvailableImageModes();
for (std::vector<std::pair<int, XnMapOutputMode > >::const_iterator it = modes.begin(); it != modes.end(); ++it)
{
cout << it->first << " = " << it->second.nXRes << " x " << it->second.nYRes << " @ " << it->second.nFPS << endl;
}
}
}
else
{
openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance();
if (driver.getNumberDevices() > 0)
{
for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices(); ++deviceIdx)
{
cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName(deviceIdx) << ", product: " << driver.getProductName(deviceIdx)
<< ", connected: " << driver.getBus(deviceIdx) << " @ " << driver.getAddress(deviceIdx) << ", serial number: \'" << driver.getSerialNumber(deviceIdx) << "\'" << endl;
}
}
else
cout << "No devices connected." << endl;
cout <<"Virtual Devices available: ONI player" << endl;
}
return 0;
}
}
else
{
openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance();
if (driver.getNumberDevices() > 0)
cout << "Device Id not set, using first device." << endl;
}
unsigned mode;
if (pcl::console::parse(argc, argv, "-depthmode", mode) != -1)
depth_mode = pcl::OpenNIGrabber::Mode (mode);
if (pcl::console::parse(argc, argv, "-imagemode", mode) != -1)
image_mode = pcl::OpenNIGrabber::Mode (mode);
if (pcl::console::find_argument (argc, argv, "-xyz") != -1)
xyz = true;
pcl::OpenNIGrabber grabber (device_id, depth_mode, image_mode);
if (xyz || !grabber.providesCallback<pcl::OpenNIGrabber::sig_cb_openni_point_cloud_rgb> ())
{
OpenNIViewer<pcl::PointXYZ> openni_viewer (grabber, argc, argv);
openni_viewer.run ();
}
else
{
OpenNIViewer<pcl::PointXYZRGBA> openni_viewer (grabber, argc, argv);
openni_viewer.run ();
}
return (0);
}