[vtkusers] How to visualize polydata after KmeansClustering?

Polly Pui polly_sukting at hotmail.com
Sat Aug 25 12:59:20 EDT 2018


Hi,

I would like to show my polydata with points and mark with colours after the KmeansClustering process.

However, I could only get the values of the points without the visualization of the data.

Can anyone please advice?

Thank you so much.


Polly

--------------------------------------------------------------------------------------

My code is as below:

int main(int argc, char* argv[])
{
// Get the points into the format needed for KMeans
vtkSmartPointer<vtkPolyData> point =
vtkSmartPointer<vtkPolyData>::New();

vtkSmartPointer<vtkPolyDataReader> reader =
vtkSmartPointer<vtkPolyDataReader>::New();
reader->SetFileName(argv[1]);
reader->Update();

point = reader->GetOutput();

vtkSmartPointer<vtkTable> inputData =
vtkSmartPointer<vtkTable>::New();

for (int c = 0; c < 3; ++c)
{
std::stringstream colName;
colName << "coord " << c;
vtkSmartPointer<vtkDoubleArray> doubleArray =
vtkSmartPointer<vtkDoubleArray>::New();
doubleArray->SetNumberOfComponents(1);
doubleArray->SetName(colName.str().c_str());
doubleArray->SetNumberOfTuples(point->GetNumberOfPoints());

for (int r = 0; r < point->GetNumberOfPoints(); ++r)
{
double p[3];
point->GetPoint(r, p);
doubleArray->SetValue(r, p[c]);
}
inputData->AddColumn(doubleArray);
}

vtkSmartPointer<vtkKMeansStatistics> kMeansStatistics =
vtkSmartPointer<vtkKMeansStatistics>::New();

#if VTK_MAJOR_VERSION <= 5
kMeansStatistics->SetInput(vtkStatisticsAlgorithm::INPUT_DATA, inputData);
#else
kMeansStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, inputData);
#endif
kMeansStatistics->SetColumnStatus(inputData->GetColumnName(0), 1);
kMeansStatistics->SetColumnStatus(inputData->GetColumnName(1), 1);
kMeansStatistics->SetColumnStatus(inputData->GetColumnName(2), 1);
kMeansStatistics->RequestSelectedColumns();
kMeansStatistics->SetAssessOption(true);
kMeansStatistics->SetDefaultNumberOfClusters(5);
//kMeansStatistics->SetMaxNumIterations(1);
kMeansStatistics->Update();
//double mean0[3];
//kMeansStatistics->GetMean(0, mean0);
// Display the results
kMeansStatistics->GetOutput()->Dump();
//Group the points according to ID number
vtkSmartPointer<vtkIntArray> clusterArray =
vtkSmartPointer<vtkIntArray>::New();
clusterArray->SetNumberOfComponents(1);
clusterArray->SetName("ClusterId");

for (int r = 0; r < kMeansStatistics->GetOutput()->GetNumberOfRows(); r++)
{
vtkVariant v = kMeansStatistics->GetOutput()->GetValue(r, kMeansStatistics->GetOutput()->GetNumberOfColumns() - 1);
//std::cout << "Point " << r << " is in cluster " << v.ToInt() << std::endl;
clusterArray->InsertNextValue(v.ToInt());
}

// Create a lookup table to map cell data to colors
vtkSmartPointer<vtkLookupTable> lut =
vtkSmartPointer<vtkLookupTable>::New();
int tableSize = (kMeansStatistics + 1, 10);
lut->SetNumberOfTableValues(tableSize);
lut->Build();

// Fill in a few known colors, the rest will be generated if needed
//ColorCells tutorial https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/ColorCells/
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
lut->SetTableValue(0, colors->GetColor4d("Black").GetData());
lut->SetTableValue(1, colors->GetColor4d("Banana").GetData());
lut->SetTableValue(2, colors->GetColor4d("Tomato").GetData());
lut->SetTableValue(3, colors->GetColor4d("Peacock").GetData());
lut->SetTableValue(4, colors->GetColor4d("Lavender").GetData());

// Output the cluster centers

vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast(kMeansStatistics->GetOutputDataObject(vtkStatisticsAlgorithm::OUTPUT_MODEL));
vtkSmartPointer<vtkTable> outputMeta = vtkTable::SafeDownCast(outputMetaDS->GetBlock(0));
//vtkSmartPointer<vtkTable> outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 1 ) );
vtkDoubleArray* coord0 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 0"));
vtkDoubleArray* coord1 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 1"));
vtkDoubleArray* coord2 = vtkDoubleArray::SafeDownCast(outputMeta->GetColumnByName("coord 2"));

for (unsigned int i = 0; i < coord0->GetNumberOfTuples(); ++i)
{
std::cout << coord0->GetValue(i) << " " << coord1->GetValue(i) << " " << coord2->GetValue(i) << std::endl;
}

vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
//polydata->SetPoints(point);
polydata->GetPointData()->AddArray(clusterArray);
polydata->GetPointData()->SetScalars(clusterArray);

// Display
vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =
vtkSmartPointer<vtkVertexGlyphFilter>::New();
#if VTK_MAJOR_VERSION <= 5
glyphFilter->SetInputConnection(polydata->GetProducerPort());
#else
glyphFilter->SetInputData(polydata);
#endif
glyphFilter->Update();

// Create a mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(glyphFilter->GetOutputPort());
mapper->SetScalarRange(0, tableSize - 1);
mapper->SetLookupTable(lut);

vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(5);

// Create a renderer, render window, and interactor
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(800, 800);

vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);

// Add the actor to the scene
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
renderWindowInteractor->SetInteractorStyle(style);

// Render and interact
renderWindow->Render();

vtkWindowToImageFilter *windowToImageFilter = vtkWindowToImageFilter::New();
windowToImageFilter->SetInput(renderWindow);
windowToImageFilter->Update();

vtkJPEGWriter *writer = vtkJPEGWriter::New();
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
writer->SetFileName("10nosepoints.jpg");
writer->Write();

renderWindowInteractor->Start();

return EXIT_SUCCESS;
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180825/b1668179/attachment.html>


More information about the vtkusers mailing list