I have a problem accessing the list of pixels of an itk::LabelObject.
This LabelObject is obtained with a itk::OrientedBoundingBoxLabelObject (https://github.com/blowekamp/itkOBBLabelMap). The original 3D image is a CBCT Dicom, inside which I'm looking for the position and orientation of a small rectangular marker.
Here is the code which leads to get the itk::LabelObject :
typedef short LabelPixelType;
typedef itk::LabelMap<LabelObjectType> LabelMapType;
typedef itk::OrientedBoundingBoxLabelMapFilter<LabelMapType> OBBLabelMapFilter;
typename OBBLabelMapFilter::Pointer toOBBLabelMap = OBBLabelMapFilter::New();
typename ToLabelMapFilterType::Pointer toLabelMap = ToLabelMapFilterType::New();
toOBBLabelMap->SetInput(toLabelMap->GetOutput());
toOBBLabelMap->Update();
LabelObjectType* labelObject = toOBBLabelMap->GetOutput()->GetNthLabelObject(idx);
OBBSize = labelObject->GetOrientedBoundingBoxSize();
I guess that accessing the pixels coordinates is possible, as it has to be accessed somehow in order to calculate the bounding boxes, but I didn't manage to do it so far. I tried then to convert the itk::LabelMap (or the LabelObject directly) to a binary image, where I could get to the pixels more easily; and convert and display this markerBinaryImage with VTK, with no more results (I get a black image).
typedef itk::LabelMapToBinaryImageFilter<LabelMapType, ImageType> LabelMapToBinaryImageFilterType;
LabelMapToBinaryImageFilterType::Pointer labelImageConverter = LabelMapToBinaryImageFilterType::New();
labelImageConverter->SetInput(toLabelMap->GetOutput());
labelImageConverter->Update();
ImageType::Pointer markerBinaryImage = labelImageConverter->GetOutput();
Does anyone have an idea about how to get to this pixels list?
You may do it like this:
for(unsigned int i = 0; i < filter->GetOutput()->GetNumberOfLabelObjects(); ++i) {
//Obtain the ith label object
FilterType::OutputImageType::LabelObjectType* labelObject =
filter->GetOutput()->GetNthLabelObject(i);
//Then, you may obtain the pixels of each label object like this:
for(unsigned int pixelId = 0; pixelId < labelObject->Size(); pixelId++) {
std::cout << labelObject->GetIndex(pixelId);
}
}
This info was obtained from the Insight Journal in the article Label object representation and manipulation with ITK. There, it says that you may obtain the bounding boxes directly using the Region attribute. I did not find the way to obtain a region in itk::LabelObject, however here is the inheritance diagram of itk::LabelObject:
If your label object is of type itk::ShapeLabelObject, you can use the GetBoundingBox() method to get the bounding box. It has other many methods worth looking at.
I tried then to convert the itk::LabelMap (...) with no more results (I get a black image).
A piece of advice here, don't try this complicated stuff to verifyother complicated stuff. You may be failing somewhere else in the chain. Instead, read the pixels like I said before and check out the data. Good Look!
Related
I am working on DICOM images (CT scans) & would like to isolate some structures of interest in my picture such as human organs (like the aorta, cf the image enclosed). I am coding in C++ with the help of ITK & VTK.
Let's assume these organs have a particular brightness intensity, therefore I can automatically identify them by using a region-growing algorithm (code below). In order to do so, I previously computed some threshold values based on the mean & standard deviation values of the voxels belonging to the organ.
How can I only keep the aorta in my image with the help of ITK/VTK features? I guess that what I'm looking for is a filter that would do the exact opposite of the ITK mask image filter.
Please find the (pseudo) code corresponding to the organ isolation below. I computed a 5 voxels dilation on the result of the region-growing to be sure to include all voxels of the organ and to have a sufficient margin around the organ after cropping.
typedef short InputPixelType;
typedef unsigned char OutputPixelType;
const int Dimension = 3;
typedef itk::Image< InputPixelType, Dimension > InputImageType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
// Region growing
typedef itk::ConnectedThresholdImageFilter< InputImagetype,
OutputImagetype > ConnectedFilterType;
ConnectedFilterType::Pointer connectedThreshold = ConnectedFilterType::New();
connectedThreshold->SetInput(input);
connectedThreshold->SetUpper(upperThreshold);
connectedThreshold->SetLower(lowerThreshold);
//Initializing seed
InternalImagetype::IndexType index;
index[0] = seed_x;
index[1] = seed_y;
connectedThreshold->SetSeed(index);
// Dilate the resulting region-growing of 5 voxels for safety
typedef itk::BinaryBallStructuringElement< OutputImageType,
Dimension > StructuringElementType;
typedef itk::BinaryDilateImageFilter< OutputImageType,
OutputImageType, StruturingElementType > DilateFilterType;
StructuringElementType structuringElement;
structuringElement.SetRadius(5);
structuringElement.CreateStructuringElement();
DilateFilterType::Pointer dilateFilter = DilateFilterType::New();
dilateFilter->SetInput(connectedThreshold->GetOutput());
dilatefilter->SetKernel(structuringElement);
// Saving the results of the RG+dilation
typedef itk::ImageFileWriter< OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetInput(dilateFilter->GetOutput());
writer->SetFileName("organ-segmented-with-dilation.mhd");
try {
writer->Update();
} catch(itk::ExceptionObject& err) {
std::cerr << "Exception caught! " << err.what() << std::endl;
return EXIT_FAILURE;
}
// What to do next to crop the input image with this region-growing?
Any help or remark is welcomed.
Mask filter itself can do the opposite of what it usually does. By default, masking value is 0, and so is outside value. This means that parts of image which correspond to non-zero part of the mask are kept, and the rest is zeroed out. If this is not what you want, you can easily invert the logic by setting different masking and outside values.
For the record, I solved my problem using the ITK mask negated filter, which contrarily to the basic mask filter directly answers the issue.
Say I'm processing an image and calculating some value at every pixel in the image like so:
int i = 0;
uchar* p;
p = imgMat.ptr<uchar>(0);
for ( i = 0; i < imgMat.rows * imgMat.cols; ++i)
{
int val = some calculation that returns an int;
}
I want to keep track of the top 50, say, values returned while processing the image. I also want to keep track of the location in the image where that value came from (x, y or pointer, doesn't matter).
I looked into heaps as an efficient way to keep track of the top response values but I don't know how I can also keep track of the location in the image that returned those responses. Basically I need an fast, efficient way to keep track of the top n responses in the image and the location of those responses, if you see what I mean. Thanks greatly in advance for any help.
I'm trying to bring 2 vtkPolyData objects closer to each other without them intersecting. I would like to "test" if one is inside the other with a simple boolean function. My first thought was to use vtkBooleanOperationPolyDataFilter with the datasets as inputs and calculate the intersection and then check if the resulting PolyData object was a NULL object. This however, does not give the desired result.
The code I'm currently using looks like this:
bool Main::Intersect(double *trans)
{
vtkSmartPointer<vtkPolyData> data1 = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPolyData> data2 = vtkSmartPointer<vtkPolyData>::New();
data1->ShallowCopy(this->ICPSource1);
data2->ShallowCopy(this->ICPSource2);
//This piece is just to reposition the data to the position I want to check
for (unsigned int k=0; k<3; k++)
{
trans[k]/=2;
}
translate(data2, trans);
for (unsigned int k=0; k<3; k++)
{
trans[k]*=-1;
}
translate(data1, trans);
//This is my use of the actual vtkBooleanOperationPolyDataFilter class
vtkSmartPointer<vtkBooleanOperationPolyDataFilter> booloperator = vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
booloperator->SetOperationToIntersection();
booloperator->AddInputData(data1);
booloperator->AddInputData(data2);
booloperator->Update();
if (booloperator->GetOutput()==NULL)
return 0;
else
return 1;
}
Any help regarding this issue is highly appreciated. Also, I don't know if the "vtkBooleanOperationPolyDataFilter" class is really the best one to use, it's just something I found and thought might work.
Thanks in advance,
Xentro
EDIT: I said this doesn't give the desired result but it does improve my result. It has some kind of influence on my movement criterion (which was the point) but in the end result the datasets still intersect sometimes.
You can call PolyDataObject->GetBounds() for both your objects and compare their values. This does only work, of course, if your objects intersect first at their boundaries. But for intersection of simple geometries this should provide a light-weight solution. See here for an example.
Regarding the vtkBooleanOperationPolyDataFilter I can only say that I tried to use it before, too, and it did not work at all how I wanted it to. In my searches I found many other people complaining about it.
EDIT: Did you try the vtkPolyDataIntersectionFilter? The class reference can be found here.
vtkIntersectionPolyDataFilter computes the intersection between two vtkPolyData objects. The first output is a set of lines that marks the intersection of the input vtkPolyData objects. The second and third outputs are the first and second input vtkPolyData, respectively. Optionally, the two output vtkPolyData can be split along the intersection lines.
I'm working on a program for image processing. At the present stage I split a CV_64FC3 into 3 colour channels, RGB, then use this as the data for a QCPColorMap.
The implementation is like this:
for(int col = 0; col < image.cols; ++col) {
for(int row = 0; row < image.rows; row++) {
colorMap->data()->setCell(row,col,rotated_matrix.at<double>(row,col));
}
}
Where rotated_matrix is a CV_64FC1 cv::Mat. This works fine and displays the colour map accordingly.
My question is can I pass through a 3 channel cv::Mat (CV_64FC3) and assign this to the data points in the QCPColorMap?
I've had a look at the documentation and as far as I can see the only variables that colorMap->data()->setCell or colorMap->data()->setData can accept are keyIndex, valueIndex, z which represent essentially x coordinate, y coordinate and then the colour value itself.
I can't seem to find a way to modify the number of channels/layers in the image to assign.
Am I missing something here?
Cheers
Mitch
Here's a somewhat painful way: put multiple instances of QPColorMap over each other and use the alpha channel to toggle off selected ones. I suppose one could sub-class QPColorMap and access QRgb that way, but that would be even harder.
This does seems like a target for modification in QCustomPlot. My sample application: show a grayscale image (e.g., a brain) with a color overlay indicating either a region of interest or an "activated" or somehow abnormal area. For this one needs access to the RBG fields.
I would like to calculate the x and y component of the gradient of a 2D image. As in MATLAB is calculated with [dT2,dT1] = gradient(T);
ReaderType::Pointer T_g // image
FilterType::Pointer gradientFilter = FilterType::New();
gradientFilter->SetInput( T_g->GetOutput());
gradientFilter->Update();
With this sentence, I get the result, but I want to have the x-component and the y-component
gradientFilter->GetOutput()
Is there any method to extract it? I am looking for it but I have no positive result!
Thanks so much
Antonio
The output of the gradientFilter will be a vector image. I assume from your description it's
a 2d image!
ImageType::IndexType index;
index[0]=xcoord;
index[1]=ycoord;
gradientFilter->GetOutput()->GetPixel(index)[0]; // will return first component of xcoord,ycoord
http://www.vtk.org/Wiki/ITK/Examples
http://www.vtk.org/Wiki/ITK/Examples/ImageProcessing/NthElementImageAdaptor
template
class itk::NthElementImageAdaptor< TImage, TOutputPixelType >
Presents an image as being composed of the N-th element of its pixels.
It assumes that the pixels are of container type and have in their API an operator[]( unsigned int ) defined.
Additional casting is performed according to the input and output image types following C++ default casting rules.
Wiki Examples:
All Examples
Extract a component of an itkImage with pixels with multiple components
Process the nth component/element of a vector image