Толстая поверхность с ВТК

Я пытаюсь создать треугольную сетку из облаков точек, полученных наземными лазерными сканерами. Я использую алгоритм марширующих кубов библиотеки VTK. Когда я визуализирую сгенерированную сетку, она выглядит как толстая поверхность, как показано на изображении ниже:

введите здесь описание изображения

Однако я ожидал увидеть это, как показано на рисунке ниже:

введите здесь описание изображения

Не могли бы вы помочь мне с этой проблемой? Я хочу создать сетки, как показано на втором рисунке. Я с нетерпением жду ответа от вас

Кстати мой код:

int main(int argc, char* argv[])
{    
    //nokta bulutu
    vtkSmartPointer<vtkSimplePointsReader> reader =
        vtkSmartPointer<vtkSimplePointsReader>::New();
    reader->SetFileName("SIL_ARKA_ENTIRE.xyz");
    reader->Update();
    vtkPolyData* polydata = reader->GetOutput();    

    FILE *Normaloku = fopen("SIL_ARKA_ENTIRE_NORMALS.xyz", "r");
    int sirasi;
    vtkSmartPointer<vtkDoubleArray> pointNormalsArray =
        vtkSmartPointer<vtkDoubleArray>::New();
    pointNormalsArray->SetNumberOfComponents(3); //3d normals (ie x,y,z)
    pointNormalsArray->SetNumberOfTuples(polydata->GetNumberOfPoints());
    double nokta_normali[3];
    for (sirasi = 0; sirasi < 652802; sirasi++)
    {
        fscanf(Normaloku, "%lf  %lf &lf", &nokta_normali[0], &nokta_normali[1], &nokta_normali[2]);
        pointNormalsArray->SetTuple(sirasi, nokta_normali);
    }
    polydata->GetPointData()->SetNormals(pointNormalsArray);
    fclose(Normaloku);
    std::cout << "eklenen işlem bitti" << std::endl;

    double isoValue;
    double bounds[6];    
    polydata->GetBounds(bounds);
    for (unsigned int i = 0; i < 6; i += 2)
    {    
        double range = bounds[i + 1] - bounds[i];
        bounds[i] = bounds[i] - .1 * range;
        bounds[i + 1] = bounds[i + 1] + .1 * range;
    }

    vtkSmartPointer<vtkImageData> volume = vtkSmartPointer<vtkImageData>::New();
    vtkSmartPointer<vtkVoxelModeller> voxelModeller = vtkSmartPointer<vtkVoxelModeller>::New();
    voxelModeller->SetSampleDimensions(20, 20, 20);
    voxelModeller->SetModelBounds(bounds);
    voxelModeller->SetScalarTypeToFloat();
    voxelModeller->SetMaximumDistance(.1);

    //voxelModeller->SetInputConnection(reader->GetOutputPort());
    voxelModeller->SetInputData(polydata);
    voxelModeller->Update();
    isoValue = 0.0001;
    volume->DeepCopy(voxelModeller->GetOutput());
    vtkSmartPointer<vtkMarchingCubes> surface = vtkSmartPointer<vtkMarchingCubes>::New();    
#if VTK_MAJOR_VERSION <= 5
    surface->SetInput(volume);
#else
    surface->SetInputData(volume);
#endif
    surface->ComputeNormalsOff();
    surface->SetValue(1, isoValue);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->SetBackground(.1, .2, .3);
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(surface->GetOutputPort());
    mapper->ScalarVisibilityOff();    
    std::string filename = "VTK_mesh_deneme.ply";
    vtkSmartPointer<vtkPLYWriter> plyWriter = vtkSmartPointer<vtkPLYWriter>::New();
    plyWriter->SetInputConnection(surface->GetOutputPort());
    plyWriter->SetFileName(filename.c_str());
    plyWriter->Write();    
    //volume->DeepCopy(voxelModeller->GetOutput());    
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);    
    renderer->AddActor(actor);    
    renderWindow->Render();
    interactor->Start();    
    return EXIT_SUCCESS;
}

person user887912    schedule 28.04.2017    source источник


Ответы (1)


Поднимите изозначение. Вы устанавливаете его на 0,001, вместо этого используйте 0,5 для бинарного изображения, чтобы получить равноудаленную границу между белыми и черными пикселями.

person mirni    schedule 29.04.2017
comment
Уважаемый Мирни, спасибо за комментарий. Я установил изозначение на 1, и толщина поверхности значительно уменьшилась. Я также увеличил разрешение. Однако на поверхности образовались дыры. У вас есть идеи, как я могу получить поверхность без отверстий? - person user887912; 30.04.2017
comment
К сожалению, алгоритм марширующих кубов не дает никаких топологических гарантий — вы вполне можете получить дыры или дескрипторы с шумом в данных. Вы можете попытаться сгладить входное изображение, чтобы избавиться от шума, или выполнить постобработку поверхности, чтобы залатать дыры. Я не думаю, что марширующие кубы - лучший фильтр для вашей проблемы - ваши данные кажутся облаком точек, а не изображением. Попробуйте, например. Гауссовые брызги. - person mirni; 06.05.2017
comment
Вы правы, мои данные представляют собой неструктурированное облако точек. Я пытался использовать 3D делоне VTK, но полученная триангуляция состоит из множества перекрывающихся треугольников, что является нежелательным результатом для моего случая. - person user887912; 07.05.2017