3

我正在使用 PCL 构建一个应用程序,用于从 Openni Grabber 查看注册的深度云,旁边是一个带有一些按钮的面板,用于一些附加功能。我发现 QVTK 可以帮助实现这个目的。我尝试了这个基本的实现。它工作正常。我使用这种方法来修改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);
}
4

0 回答 0