2016-10-11 4 views
0
 // Sample_PCL.cpp : Defines the entry point for the console application. 
    // 

    #include "stdafx.h" 
    #define NOMINMAX 
    #include <Windows.h> 
    #include <Kinect.h>         // Kinectを使用するためのヘッダファイル 
    #include <pcl/visualization/cloud_viewer.h>   // PCLを使用して表示するためのヘッダファイル 
    #include <pcl/io/pcd_io.h>       // 点群データを保存するためのヘッダファイル(.pcd, .ply) 
    //#include <pcl/io/ply_io.h> 
    #include <pcl/point_types.h> 
    #include <iostream> 

    template<class Interface> 
    inline void SafeRelease(Interface *& pInterfaceToRelease) 
    { 
     if (pInterfaceToRelease != NULL) { 
      pInterfaceToRelease->Release(); 
     } 
    } 

    int main() 
    { 
     // Create Sensor Instance 
     IKinectSensor* pSensor; 
     HRESULT hResult = S_OK; 
     hResult = GetDefaultKinectSensor(&pSensor); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : GetDefaultKinectSensor" << std::endl; 
      return -1; 
     } 
     printf("GetDfaultKinectSensor is OK\n"); 

     // Open Sensor 
     hResult = pSensor->Open(); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::Open()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::Open is OK\n"); 

     // Retrieved Coordinate Mapper 
     ICoordinateMapper* pCoordinateMapper; 
     hResult = pSensor->get_CoordinateMapper(&pCoordinateMapper); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_CoordinateMapper()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_CoordinateMapper is OK\n"); 


     // Retrieved Color Frame Source 
     IColorFrameSource* pColorSource; 
     hResult = pSensor->get_ColorFrameSource(&pColorSource); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_ColorFrameSource()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_ColorFrameSource is OK\n"); 

     // Open Color Frame Reader 
     IColorFrameReader* pColorReader; 
     hResult = pColorSource->OpenReader(&pColorReader); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IColorFrameSource::OpenReader()" << std::endl; 
      return -1; 
     } 
     printf("IColorFrameSource::OpenReader is OK\n"); 

     // Retrieved Depth Frame Source 
     IDepthFrameSource* pDepthSource; 
     hResult = pSensor->get_DepthFrameSource(&pDepthSource); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_DepthFrameSource()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_DepthFrameSource is OK\n"); 

     // Open Depth Frame Reader 
     IDepthFrameReader* pDepthReader; 
     hResult = pDepthSource->OpenReader(&pDepthReader); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IDepthFrameSource::OpenReader()" << std::endl; 
      return -1; 
     } 
     printf("IDepthFrameSource::OpenReader is OK\n"); 

     // Retrieved Color Frame Size 
     IFrameDescription* pColorDescription; 
     hResult = pColorSource->get_FrameDescription(&pColorDescription); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IColorFrameSource::get_FrameDescription()" << std::endl; 
      return -1; 
     } 
     printf("IColorFrameSource::get_FrameDescription is OK\n"); 

     int colorWidth = 0; 
     int colorHeight = 0; 
     pColorDescription->get_Width(&colorWidth); // 1920 
     pColorDescription->get_Height(&colorHeight); // 1080 

                // To Reserve Color Frame Buffer 
     std::vector<RGBQUAD> colorBuffer(colorWidth * colorHeight); 

     // Retrieved Depth Frame Size 
     IFrameDescription* pDepthDescription; 
     hResult = pDepthSource->get_FrameDescription(&pDepthDescription); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IDepthFrameSource::get_FrameDescription()" << std::endl; 
      return -1; 
     } 
     printf("IDepthFrameSource::get_FrameDescription is OK\n"); 

     int depthWidth = 0; 
     int depthHeight = 0; 
     pDepthDescription->get_Width(&depthWidth); // 512 
     pDepthDescription->get_Height(&depthHeight); // 424 

                // To Reserve Depth Frame Buffer 
     std::vector<UINT16> depthBuffer(depthWidth * depthHeight); 

     printf("Display Point Cloud\n"); 

     // Create Cloud Viewer 
     pcl::visualization::CloudViewer viewer("Point Cloud Viewer");  // 点群のウィンドウ表示 

     while (!viewer.wasStopped()) { 
      // Acquire Latest Color Frame 
      IColorFrame* pColorFrame = nullptr; 
      hResult = pColorReader->AcquireLatestFrame(&pColorFrame); 
      if (SUCCEEDED(hResult)) { 
       // Retrieved Color Data 
       hResult = pColorFrame->CopyConvertedFrameDataToArray(colorBuffer.size() * sizeof(RGBQUAD), reinterpret_cast<BYTE*>(&colorBuffer[0]), ColorImageFormat::ColorImageFormat_Bgra); 
       if (FAILED(hResult)) { 
        std::cerr << "Error : IColorFrame::CopyConvertedFrameDataToArray()" << std::endl; 
       } 
      } 
      SafeRelease(pColorFrame); 

      // Acquire Latest Depth Frame 
      IDepthFrame* pDepthFrame = nullptr; 
      hResult = pDepthReader->AcquireLatestFrame(&pDepthFrame); 
      if (SUCCEEDED(hResult)) { 
       // Retrieved Depth Data 
       hResult = pDepthFrame->CopyFrameDataToArray(depthBuffer.size(), &depthBuffer[0]); 
       if (FAILED(hResult)) { 
        std::cerr << "Error : IDepthFrame::CopyFrameDataToArray()" << std::endl; 
       } 
      } 
      SafeRelease(pDepthFrame); 

      // Point Cloud Libraryの設定 
      // Create Point Cloud 
      pcl::PointCloud<pcl::PointXYZRGB>::Ptr pointcloud(new pcl::PointCloud<pcl::PointXYZRGB>());  // PCLの構造体 
      pointcloud->width = static_cast<uint32_t>(depthWidth);  // 点群の数 
      pointcloud->height = static_cast<uint32_t>(depthHeight); 
      pointcloud->is_dense = false; 

      for (int y = 0; y < depthHeight; y++) { 
       for (int x = 0; x < depthWidth; x++) { 
        pcl::PointXYZRGB point;  // PCLで使用する点群情報 

        DepthSpacePoint depthSpacePoint = { static_cast<float>(x), static_cast<float>(y) }; 
        UINT16 depth = depthBuffer[y * depthWidth + x]; 

        // Coordinate Mapping Depth to Color Space, and Setting PointCloud RGB 
        ColorSpacePoint colorSpacePoint = { 0.0f, 0.0f }; 
        pCoordinateMapper->MapDepthPointToColorSpace(depthSpacePoint, depth, &colorSpacePoint);  // 色の座標系 
        int colorX = static_cast<int>(std::floor(colorSpacePoint.X + 0.5f)); 
        int colorY = static_cast<int>(std::floor(colorSpacePoint.Y + 0.5f)); 
        if ((0 <= colorX) && (colorX < colorWidth) && (0 <= colorY) && (colorY < colorHeight)) { 
         RGBQUAD color = colorBuffer[colorY * colorWidth + colorX]; 
         // 色の情報を格納する 
         point.b = color.rgbBlue; 
         point.g = color.rgbGreen; 
         point.r = color.rgbRed; 
        } 

        // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ 
        CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };   // カメラ空間 
        pCoordinateMapper->MapDepthPointToCameraSpace(depthSpacePoint, depth, &cameraSpacePoint); 
        if ((0 <= colorX) && (colorX < colorWidth) && (0 <= colorY) && (colorY < colorHeight)) { 
         // 直交座標系の情報を格納する 
         point.x = cameraSpacePoint.X; 
         point.y = cameraSpacePoint.Y; 
         point.z = cameraSpacePoint.Z; 
        } 

        pointcloud->push_back(point); 
       } 
      } 

      // Show Point Cloud on Cloud Viewer 
      viewer.showCloud(pointcloud); 

      // Input Key (Exit ESC key) 
      if (GetKeyState(VK_ESCAPE) < 0) { 
       pcl::io::savePCDFile("PointCloud.pcd", *pointcloud); 
       //pcl::io::savePLYFile("test_pcd2.ply", *pointcloud);   // 最後に取得した点群を保存 
       printf("Save Point Cloud Data\n"); 

       //break; 
      } 
     } 

     // End Processing 
     SafeRelease(pColorSource); 
     SafeRelease(pDepthSource); 
     SafeRelease(pColorReader); 
     SafeRelease(pDepthReader); 
     SafeRelease(pColorDescription); 
     SafeRelease(pDepthDescription); 
     SafeRelease(pCoordinateMapper); 
     if (pSensor) { 
      pSensor->Close(); 
     } 
     SafeRelease(pSensor); 

     printf("Disconnect Kinect Sensor\n"); 



     return 0; 
    } 

이전 코드는 포인트 클라우드 라이브러리 웹 사이트의 튜토리얼에서 가져온 코드로, Kinect를 사용하여 Kinect가 실시간으로 보는 포인트 클라우드를 표시합니다. 그러므로 포인트 클라우드는 끊임없이 변화하고 있습니다. 그것이 바로 프레임을 얻고 자하는 이유입니다. 즉, 새로운 프레임을 지속적으로 캡처하는 대신에 포인트 클라우드를 고정시키고 싶습니다.포인트 클라우드 라이브러리를 사용하여 하나의 프레임을 캡처하는 방법은 무엇입니까?

여기는 제 수정입니다.

 // Sample_PCL.cpp : Defines the entry point for the console application. 
    // 

    #include "stdafx.h" 
    #define NOMINMAX 
    #include <Windows.h> 
    #include <Kinect.h>         // Kinectを使用するためのヘッダファイル 
    #include <pcl/visualization/cloud_viewer.h>   // PCLを使用して表示するためのヘッダファイル 
    #include <pcl/io/pcd_io.h>       // 点群データを保存するためのヘッダファイル(.pcd, .ply) 
    //#include <pcl/io/ply_io.h> 
    #include <pcl/point_types.h> 
    #include <iostream> 

    template<class Interface> 
    inline void SafeRelease(Interface *& pInterfaceToRelease) 
    { 
     if (pInterfaceToRelease != NULL) { 
      pInterfaceToRelease->Release(); 
     } 
    } 

    int main() 
    { 
     // Create Sensor Instance 
     IKinectSensor* pSensor; 
     HRESULT hResult = S_OK; 
     hResult = GetDefaultKinectSensor(&pSensor); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : GetDefaultKinectSensor" << std::endl; 
      return -1; 
     } 
     printf("GetDfaultKinectSensor is OK\n"); 

     // Open Sensor 
     hResult = pSensor->Open(); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::Open()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::Open is OK\n"); 

     // Retrieved Coordinate Mapper 
     ICoordinateMapper* pCoordinateMapper; 
     hResult = pSensor->get_CoordinateMapper(&pCoordinateMapper); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_CoordinateMapper()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_CoordinateMapper is OK\n"); 


     // Retrieved Color Frame Source 
     IColorFrameSource* pColorSource; 
     hResult = pSensor->get_ColorFrameSource(&pColorSource); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_ColorFrameSource()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_ColorFrameSource is OK\n"); 

     // Open Color Frame Reader 
     IColorFrameReader* pColorReader; 
     hResult = pColorSource->OpenReader(&pColorReader); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IColorFrameSource::OpenReader()" << std::endl; 
      return -1; 
     } 
     printf("IColorFrameSource::OpenReader is OK\n"); 

     // Retrieved Depth Frame Source 
     IDepthFrameSource* pDepthSource; 
     hResult = pSensor->get_DepthFrameSource(&pDepthSource); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IKinectSensor::get_DepthFrameSource()" << std::endl; 
      return -1; 
     } 
     printf("IKinectSensor::get_DepthFrameSource is OK\n"); 

     // Open Depth Frame Reader 
     IDepthFrameReader* pDepthReader; 
     hResult = pDepthSource->OpenReader(&pDepthReader); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IDepthFrameSource::OpenReader()" << std::endl; 
      return -1; 
     } 
     printf("IDepthFrameSource::OpenReader is OK\n"); 

     // Retrieved Color Frame Size 
     IFrameDescription* pColorDescription; 
     hResult = pColorSource->get_FrameDescription(&pColorDescription); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IColorFrameSource::get_FrameDescription()" << std::endl; 
      return -1; 
     } 
     printf("IColorFrameSource::get_FrameDescription is OK\n"); 

     int colorWidth = 0; 
     int colorHeight = 0; 
     pColorDescription->get_Width(&colorWidth); // 1920 
     pColorDescription->get_Height(&colorHeight); // 1080 

                // To Reserve Color Frame Buffer 
     std::vector<RGBQUAD> colorBuffer(colorWidth * colorHeight); 

     // Retrieved Depth Frame Size 
     IFrameDescription* pDepthDescription; 
     hResult = pDepthSource->get_FrameDescription(&pDepthDescription); 
     if (FAILED(hResult)) { 
      std::cerr << "Error : IDepthFrameSource::get_FrameDescription()" << std::endl; 
      return -1; 
     } 
     printf("IDepthFrameSource::get_FrameDescription is OK\n"); 

     int depthWidth = 0; 
     int depthHeight = 0; 
     pDepthDescription->get_Width(&depthWidth); // 512 
     pDepthDescription->get_Height(&depthHeight); // 424 

                // To Reserve Depth Frame Buffer 
     std::vector<UINT16> depthBuffer(depthWidth * depthHeight); 

     printf("Display Point Cloud\n"); 

     // Create Cloud Viewer 
     pcl::visualization::CloudViewer viewer("Point Cloud Viewer");  // 点群のウィンドウ表示 

     //while (!viewer.wasStopped()) { 
      // Acquire Latest Color Frame 
      IColorFrame* pColorFrame = nullptr; 
      hResult = pColorReader->AcquireLatestFrame(&pColorFrame); 
      if (SUCCEEDED(hResult)) { 
       // Retrieved Color Data 
       hResult = pColorFrame->CopyConvertedFrameDataToArray(colorBuffer.size() * sizeof(RGBQUAD), reinterpret_cast<BYTE*>(&colorBuffer[0]), ColorImageFormat::ColorImageFormat_Bgra); 
       if (FAILED(hResult)) { 
        std::cerr << "Error : IColorFrame::CopyConvertedFrameDataToArray()" << std::endl; 
       } 
      } 
      SafeRelease(pColorFrame); 

      // Acquire Latest Depth Frame 
      IDepthFrame* pDepthFrame = nullptr; 
      hResult = pDepthReader->AcquireLatestFrame(&pDepthFrame); 
      if (SUCCEEDED(hResult)) { 
       // Retrieved Depth Data 
       hResult = pDepthFrame->CopyFrameDataToArray(depthBuffer.size(), &depthBuffer[0]); 
       if (FAILED(hResult)) { 
        std::cerr << "Error : IDepthFrame::CopyFrameDataToArray()" << std::endl; 
       } 
      } 
      SafeRelease(pDepthFrame); 



      // Point Cloud Libraryの設定 
      // Create Point Cloud 
      pcl::PointCloud<pcl::PointXYZRGB>::Ptr pointcloud(new pcl::PointCloud<pcl::PointXYZRGB>());  // PCLの構造体 
      pointcloud->width = static_cast<uint32_t>(depthWidth);  // 点群の数 
      pointcloud->height = static_cast<uint32_t>(depthHeight); 
      pointcloud->is_dense = false; 

      for (int y = 0; y < depthHeight; y++) { 

       for (int x = 0; x < depthWidth; x++) { 
        //printf("scann\n"); 
        pcl::PointXYZRGB point;  // PCLで使用する点群情報 

        DepthSpacePoint depthSpacePoint = { static_cast<float>(x), static_cast<float>(y) }; 
        UINT16 depth = depthBuffer[y * depthWidth + x]; 

        // Coordinate Mapping Depth to Color Space, and Setting PointCloud RGB 
        ColorSpacePoint colorSpacePoint = { 0.0f, 0.0f }; 
        pCoordinateMapper->MapDepthPointToColorSpace(depthSpacePoint, depth, &colorSpacePoint);  // 色の座標系 
        int colorX = static_cast<int>(std::floor(colorSpacePoint.X + 0.5f)); 
        int colorY = static_cast<int>(std::floor(colorSpacePoint.Y + 0.5f)); 
        if ((0 <= colorX) && (colorX < colorWidth) && (0 <= colorY) && (colorY < colorHeight)) { 
         RGBQUAD color = colorBuffer[colorY * colorWidth + colorX]; 
         // 色の情報を格納する 
         point.b = color.rgbBlue; 
         point.g = color.rgbGreen; 
         point.r = color.rgbRed; 
        } 

        // Coordinate Mapping Depth to Camera Space, and Setting PointCloud XYZ 
        CameraSpacePoint cameraSpacePoint = { 0.0f, 0.0f, 0.0f };   // カメラ空間 
        pCoordinateMapper->MapDepthPointToCameraSpace(depthSpacePoint, depth, &cameraSpacePoint); 
        if ((0 <= colorX) && (colorX < colorWidth) && (0 <= colorY) && (colorY < colorHeight)) { 
         // 直交座標系の情報を格納する 
         point.x = cameraSpacePoint.X; 
         point.y = cameraSpacePoint.Y; 
         point.z = cameraSpacePoint.Z; 
        } 

        pointcloud->push_back(point); 
       } 
      //} 

      viewer.showCloud(pointcloud); 
      while (!viewer.wasStopped()) 
      { 
      } 
      /*pcl::io::savePCDFile("PointCloud.pcd", *pointcloud); 
      printf("Saved Point Cloud Data\n"); 

      // Show Point Cloud on Cloud Viewer 
      printf("Open viewer\n"); 
      viewer.showCloud(pointcloud); 
      while (!viewer.wasStopped()) { 

      }*/ 

      // Input Key (Exit ESC key) 
      if (GetKeyState(VK_ESCAPE) < 0) { 
       pcl::io::savePCDFile("PointCloud.pcd", *pointcloud); 
       //pcl::io::savePLYFile("test_pcd2.ply", *pointcloud);   // 最後に取得した点群を保存 
       printf("Save Point Cloud Data\n"); 

       //break; 
      } 
     } 

     // End Processing 
     SafeRelease(pColorSource); 
     SafeRelease(pDepthSource); 
     SafeRelease(pColorReader); 
     SafeRelease(pDepthReader); 
     SafeRelease(pColorDescription); 
     SafeRelease(pDepthDescription); 
     SafeRelease(pCoordinateMapper); 
     if (pSensor) { 
      pSensor->Close(); 
     } 
     SafeRelease(pSensor); 

     printf("Disconnect Kinect Sensor\n"); 



     return 0; 
    } 

수정은 주로 어느 지속적으로 포인트 클라우드를 업데이트 루프를 제거 구성 : 당신은 두 번째 코드에 주석 볼 수 있습니다.

while (!viewer.wasStopped()) 

문제는 포인트 클라우드 뷰어는 키 넥트에 의해 수신되는 데이터가 표시되지 않습니다, 나는 그것을 표시 할 수 없습니다 이유를 알고 싶은 것입니다.

+0

두 목록은 동일합니다. – Dexter

+0

@Dexter를 지적 해 주셔서 감사합니다. 방금 코드를 업데이트했습니다. 한 번 더 보시 겠어요? – user1680944

답변

1

코드는 Kinect로부터받은 첫 번째 프레임 만 표시합니다.이 프레임은 비어 있거나 유효하지 않을 수 있습니다. 당신이 가지고있는 클라우드의 포인트가 정상적인 지 확인 했습니까?

그러나 다르게 문제를 접근 할 수 있습니다 : 그대로

  1. 시각화 루프를 둡니다.
  2. registerKeyboardCallback (doc)을 사용하여 키 처리기를 등록하십시오.
  3. 특정 키를 누르면 부울을 참으로 설정하십시오.
  4. 시각화 루프에서 부울 변수가 true 인 경우 Kinect에서 프레임을 건너 뜁니다. 이전에 설정된 클라우드를 유지해야합니다.