PCLを使用して、Openni Grabberから登録された深度クラウドを表示するためのアプリケーションを、いくつかの追加機能用のボタンを備えたパネルと一緒に表示しています。QVTK がこの目的に役立つことがわかりました。この基本的な実装を試しました。それは正常に動作します。このアプローチを使用して、Qt ウィンドウで視覚化するためにopenni_viewerの例を変更しました。ただし、セグメンテーション違反が発生しています。助けていただければ幸いです。
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);
}