Get a vector at specific voxel coordinates

Hi,

I have applied a 3d sobel filter on vtkImageData like this:

vtkSmartPointer<vtkImageSobel3D> sobelFilter =
vtkSmartPointer<vtkImageSobel3D>::New();
sobelFilter->SetInputData(image);
sobelFilter->Update();

My question is how can I extract the vector field at a specific voxel coordinates. For exemple to extract a value we can do:

int coords[3] = {i, j, k};

vtkVariant variant = image->GetPointData()->GetScalars()-> GetVariantValue(input>ComputePointId(coords)); // to get 0 or 1

but what about vectors , I want to get the vector field produced by soble filter at {i,j,k] coordinates in c++? I have tried many solutions but I have not get good results.

Thank’s in advance

Regardless of number of scalar components, there many different ways to access voxel data in C++. Methods that provide a single voxel’s value (such as GetVariantValue or GetScalarComponentAsDouble) are provided only for testing, diagnostics, and single-point probing only. Since all image filters in VTK access voxel data, a good starting point is to have a look at any of the filters in VTK source code. You may also ask such pure VTK questions on VTK forum.

We might be able to give some tips here if you provide more information about your specific use case. How large is your image? How many points you would like to probe? What are you going to do with the results? Do you have any special needs or constraints?

Thank you for your suggestion. I have posted the question on VTK forum. I just want to pick up a vector at a specific voxel coordinates. It is so easy if have applied gradiant filter but with sobel filter there are few examples.

Probably very few poeple, if any, uses Sobel filter. Why do you think you need to use this filter? If you need the gradient then you would normally use the image gradient filter.

Probably they both Sobel and gradient produce vector volume (vtkImageData with 3 scalar components) as a result, so you can access the resulting voxel data exactly the same way.

I have chosen SobelFilter. Because the method which I try to implement apply the sobleFilter then the vectors obtained are normalized and negated to get the normal vectors of each voxel. Can i use the gradiant to obtain normal vector or other ways to get normal vectors from volume dara (vtkImageData)

The image gradient filter computes the surface normal vector direction. If you prefer to have the vectors normalized then run the result through vtkImageNormalize.

Thank’s for the response. I found this method but I want to be sure that I will use correct normal vectors to get the good reconstruction. That is why I confirm my ideas with you:

vtkimageData image;
vtkDataArray* inScalars;;
inScalars = input->GetPointData()->GetScalars());

image->GetPointGradient(i, j, k, inScalars, Normals[0]);

If you only want to sample a very small percentage of points at integer voxel coordinates then GetPointGradient is a good choice. Most likely the best choice (fastest, most general, most accurate) is still vtkImageGradient followed by vtkProbeFilter.

1 Like

Hi Mr;

I have applied vtkImageGradient followed by vtkImageNormalize then vtkProbeFilter to get the normal vector at each polydata point as follows:

vtkSmartPointer gradientFilter =
vtkSmartPointer::New();
gradientFilter->SetInputData(imageData); // image data is vtkimagedata
gradientFilter->Update();

vtkSmartPointer normalizeFilter =
vtkSmartPointer::New();
normalizeFilter->SetInputData(gradientFilter->GetOutput());
normalizeFilter->Update();

vtkSmartPointer polydata =
vtkSmartPointer::New();
polydata->SetPoints(points1);

vtkSmartPointer probe =
vtkSmartPointer::New();
probe->SetSourceData(normalizeFilter->GetOutput());
probe->SetInputData(polydata);
probe->Update();

however? I guess that I can recover normal vectors or at least vectors with:

vtkSmartPointer Normals =
vtkFloatArray::SafeDownCast(probe->GetOutput()->GetPointData()->GetVectors()); // or GetNormals

but this generate an error. but when I do :
probe->GetOutput()->GetPointData()->GetScalars(); instead of GetVectors , it works fine.

I have tried display the first element using

for(int i = 0; i < 1; i++) {

double val= Normals->GetValue(i);
cout << "doubleData->GetValue(" << i << "): " << val<< endl;
} 

I get a float value instead of 3d Normal vector? I Don’t understand what’s wrong

I need your help please.

To retrieve a vector from a VTK array, use methods that return “tuple”.

But according to vtk documentation, vtkImage Gradiant return scalars and not vectors . I Don’t understand how it computes vectors

Vectors, Scalars, Normals, Tensors, TCoords words on vtkDataSetAttributes interface do not refer to the type of the array. Scalars array may contain multiple scalar components (making it essentially vector data). I understand that it may be confusing and I would recommend to read the VTK textbook to get better insight into why it is like this.

1 Like