Thứ Hai, 4 tháng 2, 2013

Thư viện PCL (Phần 2)


Phần 2: Sử dụng PCL trong các project

Trong hướng dẫn này sử dụng MSVS 2010.
Các thành phần yêu cầu:
1.      PCL All-in-one installer Download
2.      QT bản 4.8.0 (download bản 32bit, hoặc bản 64bit)
3.      CMake (Download)
Chú ý khi cài đặt PCL và QT nên cài ở chế độ mặc định để đỡ phải chỉnh sửa khi tạo project. Với PCL nên thêm tùy chọn “Add PCL to system PATH for all users”
Bước 1:
Tạo một thư mục chứa dự án cần tạo (1) và một thư mục chứa file buid (2).
Trong thư mục (1) tạo các file .cpp chứa code và thêm một file CMakeList.txt chứa các tùy chọn biên dịch cho chương trình CMake.


Chi tiết file CmakeList.txt như sau:
(Ví dụ cho project pcd_write.cpp  dùng để ghi dữ liệu ra định dạng PCD)
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(MY_GRAND_PROJECT)
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcd_write_test pcd_write.cpp)
target_link_libraries(pcd_write_test ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})

Ý nghĩa của các lệnh:




cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
Yêu cầu bản CMake từ 2.6 hoặc cao hơn.

project
(MY_PROJECT)
Dòng này dùng để đặt tên cho dự án. Tên dự án trong ví dụ này là MY_PROJECT.
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
Thiết lập phiên bản tối thiểu của PCL, ở ví dụ này là 1.3. Nếu phiên bản thấp hơn sẽ báo lỗi.
Các module cần thiết cho dự án được khai báo sau từ khóa COMPONENTS            , nếu không có phần này, tất cả các module sẽ được đưa vào dự án. Ở ví dụ này, các module cần thiết là common và io.
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
Thiết lập một số tham số:
  • PCL_FOUND: Đặt 1 nếu tìm thấy PCL, các trường hợp khác không thiết lập
·         PCL_INCLUDE_DIRS: Thiết lập đường dẫn đến các file headers và headers phụ thuộc của PCL
·         PCL_LIBRARIES: Thiết lập tên của thư viện PCL khi biên dịch
  • PCL_LIBRARY_DIRSThiết lập các đường dẫn đến  nơi chứa các file thư viện PCL và  3rd party dependencies
  • PCL_COMPONENTS: Danh sách tất cả các thành phần.
  • PCL_DEFINITIONS: Liệt kê các định nghĩa tiền xử lý cần thiết và cờ biên dịch
Với một dự án thông thường thì chỉ cần thiết lập giống trong ví dụ là đủ.
add_executable(pcd_write_test pcd_write.cpp)
Add file pcd_write.cpp vào phần mã nguồn của dự án.
target_link_libraries(pcd_write_test ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})
Nơi chứa các hàm chức năng khi thực hiện chương trình. Ở đây sử dụng các thư viện common và IO.

Bước 2:
Chạy chương trình CMake:

Dòng đầu tiên là đường dẫn đến thư mục chứa code và file CmakeLists.txt. Dòng thứ 2 dẫn đến thư mục chứa project sẽ được tạo ra.
Bấm Generate sẽ hiện ra bảng thiết lập như hình vẽ. Chọn các trình biên dịch và chế độ biên dịch thích hợp.

Sau khi biên dịch thành công, trong thư mục buid sẽ chứa project tương thích với MSVS2010 và sẵn sàng để biên dịch.

Chú ý, khi biên dịch bằng MSVS 2010  thành công nhưng báo lỗi không chạy tự động được thì có thể vào thư mục Debug để tìm file  exe để chạy.

Cách trên có ưu điểm là có thể tạo project cho nhiều trình biên dịch khác ngoài MSVS. Tuy nhiên, có một cách đơn giản hơn đó là cấu hình ngay trong MSVS2010 như sau:
Tạo một empty  project C++. Chuột phải vào project đã tạo. Tìm đến phần VC++ Directories và edit các phần như trong hình vẽ thành các đường dẫn đến các thư mục chứa file thư viện đã cài đặt.
Nếu cài theo mặc định, đường dẫn sẽ như sau:
#Include Directories

C:\Program Files\PCL 1.6.0\3rdParty\VTK\include\vtk-5.8;
C:\Program Files\PCL 1.6.0\3rdParty\Qhull\include;C:\Program Files\PCL 1.6.0\3rdParty\FLANN\include;
C:\Program Files\PCL 1.6.0\3rdParty\Eigen\include;C:\Program Files\PCL 1.6.0\3rdParty\Boost\include;
C:\Program Files\PCL 1.6.0\include\pcl-1.6;C:\Program Files\OpenNI\Include;C:\Qt\4.8.0\include;

#Library Directories

C:\Program Files\PCL 1.6.0\3rdParty\VTK\lib\vtk-5.8;
C:\Program Files\PCL 1.6.0\3rdParty\Qhull\lib;C:\Program Files\PCL 1.6.0\3rdParty\FLANN\lib;
C:\Program Files\PCL 1.6.0\3rdParty\Boost\lib;C:\Program Files\PCL 1.6.0\lib;C:\Qt\4.8.0\lib;


Trong mục Linker tìm đến Input và edit
pcl_common_debug.lib
pcl_apps_debug.lib
pcl_features_debug.lib
pcl_filters_debug.lib
pcl_io_debug.lib
pcl_io_ply_debug.lib
pcl_kdtree_debug.lib
pcl_keypoints_debug.lib
pcl_octree_debug.lib
pcl_registration_debug.lib
pcl_sample_consensus_debug.lib
pcl_search_debug.lib
pcl_segmentation_debug.lib
pcl_surface_debug.lib
pcl_tracking_debug.lib
pcl_visualization_debug.lib
vtkRendering-gd.lib
QVTK-gd.lib
vtkalglib-gd.lib
vtkCharts-gd.lib
vtkCommon-gd.lib
vtkDICOMParser-gd.lib
vtkexoIIc-gd.lib
vtkexpat-gd.lib
vtkFiltering-gd.lib
vtkfreetype-gd.lib
vtkftgl-gd.lib
vtkGenericFiltering-gd.lib
vtkGeovis-gd.lib
vtkGraphics-gd.lib
vtkhdf5-gd.lib
vtkHybrid-gd.lib
vtkImaging-gd.lib
vtkInfovis-gd.lib
vtkIO-gd.lib
vtkjpeg-gd.lib
vtklibxml2-gd.lib
vtkmetaio-gd.lib
vtkNetCDF_cxx-gd.lib
vtkNetCDF-gd.lib
vtkpng-gd.lib
vtkproj4-gd.lib
vtksqlite-gd.lib
vtksys-gd.lib
vtktiff-gd.lib
vtkverdict-gd.lib
vtkViews-gd.lib
vtkVolumeRendering-gd.lib
vtkWidgets-gd.lib
vtkzlib-gd.lib
OpenGL32.Lib


   

Phần 3: Một số ứng dụng cơ bản của PCL

3.1 Đọc dữ liệu từ Kinect:

Để đọc dữ liệu thu được từ Kinect,  chúng ta có thể sử dụng OpenNIGrabber, đây là một lớp có sử dụng thư viện OpenNI có sẵn trong PCL.
Các bước thực hiện như sau:
Bước 1: Khai báo 
      #include <pcl/io/openni_grabber.h>

Bước 2:  Tạo một Grabber mới:
 
        pcl::Grabber* interface = new pcl::OpenNIGrabber();

Bước 3: Tạo callback function:
 
boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)>                                                              
      boost::bind (&SimpleOpenNIProcessor::cloud_cb_, this, _1);
// cloud_cb_ là hàm dùng để xử lý dữ liệu nhận về, ở ví dụ này cloub_cb_ để hiển thị //ra màn hình.
 
Ở các lệnh trên, dữ liệu ta thu về từ Kinect có định dạng PointXYZRGBA,  có thể sửa lại lệnh để thu về các loại dữ liệu khác. Cụ thể như sau:
-          Dữ liệu thu về là điểm ảnh mầu 3D pointXYZRGB:
void (const boost::shared_ptr<const pcl::pointCloud <pcl::pointXYZRGB>> &)
-          Dữ liệu thu về là điểm ảnh không mầu 3D pointXYZ:
void (const boost::shared_ptr<const pcl::pointCloud <pcl::pointXYZ>> &)
-          Dữ liệu thu về là ảnh RGB từ camera :
void (const boost::shared_ptr< openNI_wrapper::Image> &)
-          Dữ liệu thu về là bản đồ độ sâu:
void (const boost::shared_ptr< openNI_wrapper::DepthImage> &)

Bước 4: Kết nối hàm callback với dữ liệu cần quan tâm và nhận dữ liệu, dừng dữ liệu: 
       interface->registerCallback (f);
 
       interface->start ();
 
interface->stop ();
 

-         Hiển thị dữ liệu ra màn hình:
Để hiển thị dữ liệu ra màn hình, có thể dùng thư viện con visualization.  Thư viện này cho phép hiển thị nhiều định dạng dữ liệu khác nhau như pointXYZ, pointXYZRGB, ảnh RGB, bản đồ độ sâu…
Ví dụ để hiển thị PointXYZRGB trước tiên cần khai báo
#include <pcl/visualization/cloud_viewer.h>
Hàm hiển thị dữ liệu với đầu vào là biến cloud, cửa sổ hiển thị là viewer:
 
     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }

Toàn bộ Code chương trình đọc dữ liệu từ Kinect hiển thị ra màn hình như sau:
#include <pcl/io/openni_grabber.h>
 #include <pcl/visualization/cloud_viewer.h>
 
 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}
 
     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }
 
     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();
 
  boost::function<void (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);
 
       interface->registerCallback (f);
 
       interface->start ();
 
       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }
 
       interface->stop ();
     }
 
     pcl::visualization::CloudViewer viewer;
 };
 
 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }
File makelists.txt để tạo dự án MSVS 2010 từ Cmake
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
 
project(openni_grabber)
 
find_package(PCL 1.2 REQUIRED)
 
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
 
add_executable (openni_grabber openni_grabber.cpp)
target_link_libraries (openni_grabber ${PCL_LIBRARIES})

Kết quả:
Ảnh thực tế

Ảnh thu được khi chạy chương trình ở trên.:


 

3.2 Class bộ lọc sử dụng Voxel Grid:

Nhằm tăng tốc độ xử lý, ta có thể đưa dữ liệu qua bộ lọc voxel Grid để giảm số lượng điểm ảnh và giới hạn vùng lấy dữ liệu phía trước cảm biến.
Tập hợp các điểm gần nhau sẽ chỉ lấy một điểm đại diện.
Các hàm PCL cung cấp cho bộ lọc bao gồm:
-         pcl::VoxelGrid<PointType> grid_;
 Khai báo một bộ lọc VoxtelGrid có tên là grid_, PointType là các kiểu biểu diễn điểm như PointXYZ, PointXYZRGB…
-         grid_.setLeafSize (leaf_size_x, leaf_size_y, leaf_size_z);
Chọn mật độ điểm theo các chiều lần lượt là X,Y,Z. Đơn vị là Met
-         grid_.setFilterFieldName (field_name);
Chiều cần giới hạn ví dụ giới hạn theo chiều Z
-         grid_.setFilterLimits (min_v, max_v);
Thiết lập khoảng giới hạn hoảng giới hạn

Code tham khảo:

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/console/parse.h>
#include <pcl/common/time.h>

// Ham Tinh framerate trung binh (Hz)
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    double now = pcl::getTime (); \
    ++count; \
    if (now - last >= 1.0) \
    { \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)

// Khuon mau ham Voxel Grid, PointType co the la PointXYZ,PointXYZRGB,...
template <typename PointType>
class OpenNIVoxelGrid
{
      
  public:
    typedef pcl::PointCloud<PointType> Cloud;
    typedef typename Cloud::Ptr CloudPtr;
    typedef typename Cloud::ConstPtr CloudConstPtr;

       pcl::VoxelGrid<PointType> grid_;                // Bo loc VoxelGrid
       pcl::visualization::CloudViewer viewer; // Khai bao 1 cua so hien thi
       std::string device_id_;                                // Id cua thiet bi
       boost::mutex mtx_;                                     // Quan ly mutex
       CloudConstPtr cloud_;                                  // Con tro pointCloud const
       //Ham tao
    OpenNIVoxelGrid (const std::string& device_id = "",
                   const std::string& field_name = "z"float min_v = 0, float max_v = 5.0,
//Gioi han theo truc z tu 0-5m
float leaf_size_x = 0.01, float leaf_size_y = 0.01, float leaf_size_z = 0.01) // Tham so cua bo loc
    : viewer ("PCL OpenNI VoxelGrid Viewer")
    , device_id_(device_id)
    {
      grid_.setLeafSize (leaf_size_x, leaf_size_y, leaf_size_z);
      grid_.setFilterFieldName (field_name);
      grid_.setFilterLimits (min_v, max_v);
    }
   
    void
    cloud_cb_ (const CloudConstPtr& cloud)//Ham callback khi nhan duoc tin hieu tu Kinect
    {
      set (cloud);
    }

    void
    set (const CloudConstPtr& cloud)// Ham set du lieu
    {
         // Khoa mutex trong khi set du lieu
      boost::mutex::scoped_lock lock (mtx_);
      cloud_  = cloud;
    }

    CloudPtr
    get ()
    {
         // Khoa khi swap du lieu va reset chung.
      boost::mutex::scoped_lock lock (mtx_);
      CloudPtr temp_cloud (new Cloud);
       // Truyen tham so cho bo loc
      grid_.setInputCloud (cloud_);
      grid_.filter (*temp_cloud);

      return (temp_cloud);
    }

    void
    run ()
    {
         // Nhan du lieu tu Kinect
      pcl::Grabber* interface = new pcl::OpenNIGrabber (device_id_);

      boost::function<void (const CloudConstPtr&)> f = boost::bind (&OpenNIVoxelGrid::cloud_cb_, this, _1);
      boost::signals2::connection c = interface->registerCallback (f);
     
      interface->start ();
     
      while (!viewer.wasStopped ())
      {
        if (cloud_)
        {
          FPS_CALC ("drawing");// Hien thi framerate trung binh (Hz)
          viewer.showCloud (get ());
        }
      }

      interface->stop ();
    }


};


int
main (int argc, char ** argv)
{


  double min_v = 0.5, max_v = 1.4;
  std::string field_name ("z");

  double leaf_x = 0.01, leaf_y = 0.01, leaf_z = 0.01;
  pcl::OpenNIGrabber grabber ("");
      OpenNIVoxelGrid<pcl::PointXYZI> v ("", field_name, min_v, max_v, leaf_x, leaf_y, leaf_z);
    v.run ();


  return (0);
}

18 nhận xét:

  1. Bài viết hay quá. Mình đã làm theo hướng dẫn của bạn
    1. Cài PCL All-in-one ( tuy nhiên mình chỉ chọn cài PCL)
    2. Cài riêng các phần mềm trong all in one, như vtk,flann,..
    3. Cấu hình lại include directories , lib... theo đường dẫn mới trong vs10
    4. Chạy thử ví dụ của bạn
    -> Đã thành công
    http://i10.photobucket.com/albums/a128/anhdungbk25/KinectSnapshot-08-58-26_zps328b26fc.png

    Tuy nhiên thì mình không hiểu rõ lắm về xử lý ảnh của kinect. Bạn có thể giới thiệu cho mình một số tài liệu về kinect và pcl để hiểu rõ hơn về ví dụ của bạn được không?

    Trả lờiXóa
  2. Chúc mừng bạn đã làm thành công. Mình không hiểu ý bạn khi nói về xử lý ảnh của Kinect :D. Ý bạn là về nguyên lý của Kinect hay cách sử dụng các hàm hỗ trợ xử lý ảnh của nó. Tài liệu chuẩn nhất là help hướng dẫn của nó rồi bạn nhé. Cứ từ đấy mà tìm hiểu thôi. Ngoài ra bạn xác định rõ mình sử dụng Kinect để làm gì thì mới tìm hiểu nhanh đc.

    Trả lờiXóa
  3. ý mình là các hàm hỗ trợ xử lý ảnh của pcl.
    Help là phần: http://pointclouds.org/documentation/
    này hả bạn, mình thấy nó chung chung quá.
    Mục tiêu của mình là dung kinect để xác định vị trí các điểm leo trên một bức tường climbing wall -> xác định vị trí các hold trên đó. Hi vì mình bên mechanic nên mảng này gà mờ quá. Có gì khó mình lại hỏi thêm bạn nhé :)

    Trả lờiXóa
  4. hay quá.. mà anh có thể làm hướng dẫn vơi phần mềm code blocks , với openframeworks dc ko ạ!

    Trả lờiXóa
  5. Anh ơi em đang làm đồ án tốt nghiệp dề tài là :Tái tạo ảnh 3D từ đối tượng thế giới thực bằng cảm biến độ sâu.
    Anh cho em hỏi môi trường tái tạo ảnh 3D point cloud visualization là 1 bộ thư viện và em phải viết code trên c++ ha anh, rồi kết nối Kinect với môi truongf tái tạo 3d để scan thế giới thực vào môi trường 3d là làm giống những bài viết của anh ạ . Mong anh phản hồi cảm ơn

    Trả lờiXóa
  6. @Thành: Nếu nội dung đồ án đúng như tên của nó thì bạn chẳng phải làm gì cả (Trong trường hợp cảm biến độ sâu như bạn nói là Kinect). Việc thu đc ảnh và hiển thị dưới dạng 3D là một trong những việc cơ bản của bộ thư viện này, bạn tham khảo ví dụ của nó nhé. Còn nếu sử dụng 1 cảm biến khác thì mình chịu. Hơn nữa bạn đặt câu hỏi hơi khó hiểu :D.
    Kinect cung cấp dữ liệu đầu vào, bộ thư viện này có nhiệm vụ xử lý dữ liệu đấy để ra được kết quả là các hình ảnh 3D như bạn thấy đấy. Ngoài Kinect, bộ thư viện này còn hỗ trợ nhiều cảm biến khác. Bạn lên trang chủ của PCL để tìm hiểu thêm nhé.

    Trả lờiXóa
  7. Bài viết của anh rất dễ hiểu, em đã build thành công và không lỗi.
    nhưng khi chạy nó lại thông báo là "the system cannot find the file specified", em vào thư mục debug chạy file .exe thì thông báo nó "runtime error this application has requested the runtime to terminate it in an unusual way" . hic
    Anh có kinh nghiệm gì chỉ giáo em với ...........

    Trả lờiXóa
  8. Em chào anh Kiên, chào mọi người,

    Em không hiểu làm sao có thể sử dụng đồng thời OpenCV và PCL ạ. ?

    Em Huy

    Trả lờiXóa
  9. Lâu lắm lại mới vào blog :D
    @Tien Tran Phi: Mình thì không biết cụ thể lỗi của bạn là ntn nhưng thông thường lỗi này gặp phải khi thiếu thư viện hoặc do phần cứng kết nối ko chuẩn. Chẳng hạn bạn viết chương trình giao tiếp UART trên máy tính nhưng không có cổng COM nối vào cũng gặp phải hiện tượng này. Bạn thử kiểm tra lại xem.

    @Huy: Mình chưa dùng OpenCV bao giờ cả. Tuy nhiên 2 cái này độc lập nhau, bạn cứ include PCL sau đó include OpenCV vào dự án như các hướng dẫn bình thường thôi. Còn kết hợp 2 cái với nhau thì phải tùy tình huống cụ thể, sao cho giá trị truyền vào các hàm của 2 thư viện phù hợp.
    Mình vừa GG ra link sau, bạn tham khảo xem nhé:
    http://ramsrigoutham.com/2012/06/28/integrating-pcl-and-opencv-passthrough-filter-example/

    Trả lờiXóa
    Trả lời
    1. Em cám ơn anh !

      Em sẽ thử và báo kết quả để trao đổi cùng anh và mọi người. Nếu như anh ít có thời gian vào lại blog em có thể liên lạc với anh qua email được không ạ ?

      Anh cho em xin địa chỉ email. Em cám ơn ạ !

      Xóa
    2. Em chào anh Kiên, chào mọi người.

      Em đã sử dụng được OpenCV và PCL trong cùng một project, thực ra bản chất việc sử dụng các thư viện là như nhau, chỉ cần đảm bảo cấu hình đúng để trình dịch có thể dịch các mã nguồn viết sẵn ra mà thôi.

      Hiện tại em đang gặp một khó khăn khác, rất mong anh và mọi người cho ý kiến.

      Em đã test project trên các bộ dữ liệu thu sẵn ( RGB, depth, Acc) và sử dụng chúng làm đầu vào cho chương trình thông qua Command Argument của VS2010. Tuy nhiên điều này không đảm bảo tiêu chí của project của em, vì đây là một project dẫn hướng có người khiếm thị nên phải thu và xử lý dữ liệu thời gian thực.

      Em đã viết xong code và build thành công, nhưng khi chạy lại không thu được dữ liệu.

      void OnlineObstacleDetector::run(char* argv[])
      {
      CloudViewer viewer("Cloud Viewer");

      // create a new grabber for OpenNI devices
      pcl::Grabber* interface = new pcl::OpenNIGrabber();

      // make callback function from member functions
      boost::function::ConstPtr&)> f = boost::bind (&OnlineObstacleDetector::detect, this, _1);

      // connect callback function for desired signal. In this case its a point cloud with color values
      boost::signals2::connection c = interface->registerCallback (f);

      viewer.runOnVisualizationThread (boost::bind(&OnlineObstacleDetector::visualize, this, _1), "viz_cb"); // Ket noi ham callback voi du lieu can quan tam

      interface->start ();

      while (!viewer.wasStopped ()) {
      boost::this_thread::sleep(boost::posix_time::seconds(1));
      }

      interface->stop ();


      Có một điểm em làm khác anh là em không tải bản PCL -all-in-one mà tải riêng các thư viện. Sau đó tải driver SensorKinect của PrimeSense và cài lên máy. Em nghĩ như thế là đủ và chỉ cần khi chạy chương trình thì dữ liệu sẽ được thu.


      Tuy nhiên không có kết quả gì, em gặp lỗi khi run chương trình, em nghĩ em chưa biết sử dụng Command Argument của Visual như thế nào cho đúng trong trường hợp nay, em cũng không biết mình thiếu driver nào không ?

      Anh cho em lời khuyên ạ !

      Cám ơn anh !

      Xóa
    3. Mình vừa cài đặt để khi có bình luận sẽ tự động gửi vào email rồi. Bạn cứ trao đổi ở đây cũng được :D.
      Còn nếu cần thì email của mình là letrungkien.k53.hut@gmail.com.
      Mình ko dám hứa đâu, vì phần cứng cũng đã trả cho thầy từ 2 năm trước rồi, code ko dùng cũng quên mà có muốn test lại cũng ko được.

      Ngày xưa mình cũng làm để robot xử lý thời gian thực mà, cái này mình nghĩ với ứng dụng của bạn thì OK thôi. Bạn đã làm các ví dụ cơ bản về thu nhận ảnh và một số bộ lọc cơ bản như ở bài viết của mình chưa. Nên làm từng bước một nhé. Thời mình làm đồ án bộ thư viện nó chưa hỗ trợ win8 nên mình toàn phải làm trên win7, ko biết bạn dùng bản win nào? Bộ thư viện phiên bản bao nhiêu?
      Nếu có thời gian bạn thử thực hiện đúng như hướng dẫn của mình để biết phần cứng đã ok chưa rồi hãy làm tiếp nhé.

      Xóa
  10. Bạn cho mình hỏi với.M dùng Kinect module 1473 có được không vậy.

    Trả lờiXóa
    Trả lời
    1. Mình cũng không nhớ rõ module Kinect cũ của mình là gì :D. Chỉ biết là nó có 2 phiên bản là cho XBOX và cho PC. Mình dùng bản cho PC :D.

      Xóa
    2. Mấy hàm này dùng như thế nào vậy bạn:
      setModelType(pcl::SACMODEL_PLANE);
      setMethodType(pcl::SAC_RANSAC);
      setDistanceThreshold(0.02);
      setInputCloud(cloud_filtered);
      setIndices(inliers);
      filter(*cloud_cluster);
      getMinMax3D(&cloud_cluster, min_point, max_point);
      Chỉ mình với.

      Xóa
  11. Ak.Mà PCL có chạy được trên W7 64bit không vậy a?

    Trả lờiXóa
  12. ​Dear A Kiên.

    Hiên tại e đang biên dịch PCL nhưng chưa được. Và anh cho e hỏi là PCL có nhận file input là *.ply không. Định dạng file như đính kèm. ​

    Trả lờiXóa
  13. A cho em hỏi khi cài đặt thì bị lỗi ở phần OpenNI và Nite ,lỗi như sau " Please install OpenNI version 1.2.0.4 or higher" ... Anh có thể hỗ trợ giúp em phần này qua mail: thaitanloi365@gmail.com được không vậy

    Trả lờiXóa