Hello all,
I am working with a .vtk file of the brain which consists of principal eigenvectors.
Please see the thresholded brain image and zoomed up version(glyphs) in the images.
Now I want to pick a seed point in the brain by mouse click and gradually grow the tract following the vector points until 1000 iterations with the equation, p1 = p0 + v(p0)*s where s is the stepsize less than one voxel.
for i th iteration points, p(i) = p(i-1) + v(p(i-1)) *s
So far I am using the following codes which pick the seed point but end up in segmentation fault
. I did not implement the tract growing part… for that I require help.
Code:
#include <vtkSmartPointer.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkNrrdReader.h>
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkStructuredPointsReader.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkProperty.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkQuadricDecimation.h>
#include <vtkStructuredPoints.h>
#include <vtkPointData.h>
#include <vtkFloatArray.h>
#include <vtkImageData.h>
#include <vtkThresholdPoints.h>
#include <vtkDataSet.h>
//for picking points
#include <vtkPointPicker.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkRendererCollection.h>
class MyMouseCallback : public vtkInteractorStyleTrackballCamera
{
public:
MyMouseCallback()
{
}
~MyMouseCallback()
{
}
static MyMouseCallback* New()
{
MyMouseCallback* callback = new MyMouseCallback();
return callback;
}
virtual void OnLeftButtonDown() override
{
std::cout << "hello" << std::endl;
int x, y;
this->Interactor->GetEventPosition(x, y);
std::cout << "Picked pixel: " << x << " " << y << std::endl;
// figure out where that maps to in the scene (which point of which mesh?)
// we need to know the picker and renderer
vtkSmartPointer < vtkPointPicker > picker = dynamic_cast <vtkPointPicker *> (this->Interactor->GetPicker());
vtkSmartPointer < vtkRenderWindow > window = this->Interactor->GetRenderWindow();
vtkSmartPointer < vtkRenderer > renderer = window->GetRenderers()->GetFirstRenderer();
picker->Pick(x, y, 0, renderer);
std::cout << "Picked point id: " << picker->GetPointId() << std::endl ;
//std::cout << "Picked point id: " << picker->GetCellId() << std::endl;
// we need to figure out where the mesh is
vtkSmartPointer < vtkPolyDataMapper > mapper = dynamic_cast <vtkPolyDataMapper*> (picker->GetMapper());
if (mapper != NULL)
{
vtkSmartPointer < vtkPolyData > mesh = mapper->GetInput();
// get the scalars from the mesh so we can change it
vtkSmartPointer < vtkIntArray > scalars = dynamic_cast <vtkIntArray*> (mesh->GetPointData()->GetScalars());
// change the scalars
scalars->SetValue ( picker->GetPointId(), 1 ) ;
mesh->Modified();
}
// now go back to doing nromal left button things
vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}
};
int main(int argc, char* argv[])
{
vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
//vtkSmartPointer<vtkXMLPolyDataReader> reader2 = vtkSmartPointer<vtkXMLPolyDataReader>::New();
//reader->SetFileName("../../PEoutput.vtk");
reader->SetFileName(argv[1]);
reader->Update();
//std::cout << reader->GetOutput()->GetNumberOfPoints() << std::endl; //1762560
//clean up codes:
vtkSmartPointer<vtkFloatArray> brain = vtkSmartPointer<vtkFloatArray>::New();
brain->SetNumberOfValues(reader->GetOutput()->GetNumberOfPoints());
for (vtkIdType idx = 0; idx < reader->GetOutput()->GetNumberOfPoints(); idx++)
{
double* v = reader->GetOutput()->GetAttributes(vtkDataSet::POINT)->GetVectors()->GetTuple3(idx);
if (v[0] * v[1] * v[2] > 0)
{
brain->SetValue(idx, 1);
}
else
{
brain->SetValue(idx, 0);
}
}
reader->GetOutput()->GetPointData()->SetScalars(brain);
vtkSmartPointer<vtkThresholdPoints> thresh = vtkSmartPointer<vtkThresholdPoints>::New();
thresh->ThresholdByUpper(0.5);
thresh->SetInputData(reader->GetOutput());
thresh->Update(); //this is also the reader image
//vtkSmartPointer<vtkPolyData> thresholdImage = thresh->GetOutput();
/*
vtkSmartPointer<vtkImageDataGeometryFilter> geometryFilter = vtkSmartPointer<vtkImageDataGeometryFilter>::New();
geometryFilter->SetInputConnection(reader->GetOutputPort());
geometryFilter->Update();
*/
//vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
//mapper->SetInputData(thresh->GetOutput());
//mapper->SetInputConnection(geometryFilter->GetOutputPort()); //geometryFilter
//vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
//actor->SetMapper(mapper);
//actor->GetProperty()->SetColor(1, 0, 0);
// Compute & Visualize Normal Vectors
/*
vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
normalsFilter->SetInputData(geometryFilter->GetOutput());
normalsFilter->ComputePointNormalsOn();
normalsFilter->Update();
*/
vtkSmartPointer<vtkArrowSource>oneArrow = vtkSmartPointer<vtkArrowSource>::New();
oneArrow->Update();
vtkSmartPointer<vtkGlyph3D> lotsOfArrows = vtkSmartPointer<vtkGlyph3D>::New();
lotsOfArrows->SetSourceData(oneArrow->GetOutput());
lotsOfArrows->SetInputData(thresh->GetOutput()); //gerometryFilter
lotsOfArrows->OrientOn();
lotsOfArrows->SetScaleFactor(1);
lotsOfArrows->SetColorModeToColorByVector();
lotsOfArrows->Update();
vtkSmartPointer < vtkPolyDataMapper > arrowMapper = vtkSmartPointer < vtkPolyDataMapper > ::New();
arrowMapper->SetInputData(lotsOfArrows->GetOutput());
vtkSmartPointer<vtkActor> arrowActor = vtkSmartPointer<vtkActor>::New();
arrowActor->SetMapper(arrowMapper);
arrowActor->GetProperty()->SetColor(1, 0, 0); //
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(arrowActor); //arrowActor //actor
renderer->SetBackground(1, 1, 1);
renderWindow->Render();
renderWindow->SetSize(300, 300);
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
// create a point picker
vtkSmartPointer < vtkPointPicker > pointPicker = vtkSmartPointer < vtkPointPicker >::New();
interactor->SetPicker(pointPicker);
// create an interactor style
vtkSmartPointer < MyMouseCallback > interactorStyle = vtkSmartPointer < MyMouseCallback >::New();
interactor->SetInteractorStyle(interactorStyle);
interactor->Start();
return 0;
}