2017-10-09 1 views
0

카메라 위치에 따라 포인트 클라우드 (즉, 3D 점 구름의 2D 투영)를 2.5-D 뷰로 생성하는 가상 스캐너가 있습니다. vtkCamera.GetProjectionTransformMatrix()을 사용하여 world/global에서 camera coordinate로 변환 행렬을 얻습니다.색상 정보를 보존하는 가상 카메라 시뮬레이션

그러나 입력 점 구름이 포인트에 대한 색상 정보를 가지고 있다면이를 보존하고 싶습니다.

이제
boost::shared_ptr<pcl::visualization::PCLVisualizer> vis; // camera location, viewpoint and up direction for vis were already defined before 
vtkSmartPointer<vtkRendererCollection> rens = vis->getRendererCollection(); 
vtkSmartPointer<vtkRenderWindow> win = vis->getRenderWindow(); 

win->SetSize(xres, yres); // xres and yres are predefined resolutions 
win->Render(); 

float dwidth = 2.0f/float(xres), 
    dheight = 2.0f/float(yres); 

float *depth = new float[xres * yres]; 
win->GetZbufferData(0, 0, xres - 1, yres - 1, &(depth[0])); 

vtkRenderer *ren = rens->GetFirstRenderer(); 
vtkCamera *camera = ren->GetActiveCamera(); 
vtkSmartPointer<vtkMatrix4x4> projection_transform = camera->GetProjectionTransformMatrix(ren->GetTiledAspectRatio(), 0, 1); 

Eigen::Matrix4f mat1; 
for (int i = 0; i < 4; ++i) 
    for (int j = 0; j < 4; ++j) 
     mat1(i, j) = static_cast<float> (projection_transform->Element[i][j]); 

mat1 = mat1.inverse().eval(); 

, MAT1 카메라 뷰에 좌표를 변환하는 데 사용됩니다 :

pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud; 

int ptr = 0; 
for (int y = 0; y < yres; ++y) 
{ 
    for (int x = 0; x < xres; ++x, ++ptr) 
    { 
     pcl::PointXYZ &pt = (*cloud)[ptr]; 

     if (depth[ptr] == 1.0) 
     { 
      pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN(); 
      continue; 
     } 

     Eigen::Vector4f world_coords(dwidth * float(x) - 1.0f, 
      dheight * float(y) - 1.0f, 
      depth[ptr], 
      1.0f); 
     world_coords = mat1 * world_coords; 

     float w3 = 1.0f/world_coords[3]; 
     world_coords[0] *= w3; 
     world_coords[1] *= w3; 
     world_coords[2] *= w3; 

     pt.x = static_cast<float> (world_coords[0]); 
     pt.y = static_cast<float> (world_coords[1]); 
     pt.z = static_cast<float> (world_coords[2]); 
    } 
} 

내가 가상 스캐너 컬러 정보 pcl::PointXYZRGB 점 구름을 반환하려면 여기

는 관련 라인이다 .

VTK에 익숙한 사람으로부터 이것을 구현하는 방법에 대한 도움은 내 시간을 절약 할 수 있습니다.

여기에 이미 질문 된 관련 질문을 놓친 것일 수도 있습니다.이 경우에는 그 점을 지적 해주십시오. 감사합니다. 내가 정확하게 당신이 포인트가 win RenderWindow의로 렌더링 된의 색상을 얻을 것인지 이해한다면

답변

1

, 당신은

float* pixels = win->GetRGBAPixelData(0, 0, xres - 1, yres - 1, 0/1)를 호출하여 렌더링 버퍼의 데이터를 얻을 수 있어야합니다.

이것은 렌더링 버퍼의 각 픽셀을 [R0, G0, B0, A0, R1, G1, B1, A1, R2....] 형식의 배열로 제공해야합니다. 0/1으로 작성한 마지막 매개 변수는 데이터를 앞면 또는 뒷면의 OpenGL 버퍼에서 가져와야하는지 여부입니다. 나는 기본적으로 이중 버퍼링을해야한다고 가정하므로 백 버퍼 ('1'사용)에서 읽으려고하지만 확실하지 않습니다.

그이 후에는 같은 포인트 (depth[ptr] != 1.0)에 속하는 모든 픽셀에 대한 두 번째 루프의 색상 얻을 수 있습니다 : 당신이 그것으로 완료되면 당신은 win->ReleaseRGBAPixelData(pixels)를 호출해야

pt.R = pixels[4*ptr]; 
pt.G = pixels[4*ptr + 1]; 
pt.B = pixels[4*ptr + 2]; 

합니다.

+0

그건 내가 원했던거야. 나는 마지막 매개 변수 (앞)를 1로 설정했다. 값을'pcl :: PointCloud '로 내보낼 때 (아마) 255로 곱해야합니다. 고마워요! – mf27

관련 문제