Function
Perform MPR operation on the mask data, obtain the sliced image, and convert it to an RGB image, and use OpenCV to display it;
Involved function points:
1. Use the vtkNIFTIImageReader class to read the nii.gz file;
2. Use the vtkImageReslice class to obtain sliced images;
3. Convert the two-dimensional unsigned char array to cv::Mat;
How to use the vtkImageReslice class to obtain sliced images, refer to notes:
// bits是input数组的类型长度:char,short,int,long,float,double等等,是sizeof(T)
void Buffer2Mat_123(const unsigned char *input, int width, int height, int bits, cv::Mat &img)
{
if (input == NULL) return;
int bytes = width * height * bits / 8;
img = cv::Mat::zeros(height, width, bits == 8 ? CV_8UC1 : CV_8UC3);
memcpy(img.data, input, bytes);
}
int main(int, char*[])
{
test_niigz_mpr();
return 0;
}
void test_niigz_mpr()
{
vtkNew<vtkNIFTIImageReader> reader;
reader->SetFileName("G:/Data/mask_data.nii.gz");
reader->Update();
int extent[6] = { 0 };
double spacing[3] = { 0 };
double origin[3] = { 0 };
double center[3] = { 0 };
reader->GetOutput()->GetExtent(extent);
reader->GetOutput()->GetSpacing(spacing);
reader->GetOutput()->GetOrigin(origin);
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);
double axialElements[16] = {
1, 0.2, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
vtkNew<vtkMatrix4x4> resliceAxes;
resliceAxes->DeepCopy(axialElements);
resliceAxes->SetElement(0, 3, center[0]);
resliceAxes->SetElement(1, 3, center[1]);
resliceAxes->SetElement(2, 3, center[2]);
vtkNew<vtkImageReslice> reslice;
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
//reslice->SetInterpolationModeToNearestNeighbor();
//reslice->SetInterpolationModeToLinear();
reslice->SetInterpolationModeToCubic();
reslice->Update();
unsigned char* edit_ptr = reinterpret_cast<unsigned char*>(reslice->GetOutput()->GetScalarPointer());
int length = reslice->GetOutput()->GetScalarSize();
int out_dims[3] = { 0 };
reslice->GetOutput()->GetDimensions(out_dims);
length = out_dims[0] * out_dims[1];
set<unsigned char> ids;
for (int i = 0; i < length; i++) {
ids.insert(edit_ptr[i]);
}
unsigned char* rgb_image_buf = new unsigned char[length * 3]{ 0 };
map<unsigned char, std::tuple<unsigned char, unsigned char, unsigned char>> color_lookup_table;
color_lookup_table.insert(make_pair(0, std::make_tuple(0, 0, 0)));
color_lookup_table.insert(make_pair(2, std::make_tuple(0, 255, 255)));
color_lookup_table.insert(make_pair(5, std::make_tuple(18, 153, 255)));
color_lookup_table.insert(make_pair(17, std::make_tuple(105, 168, 227)));
color_lookup_table.insert(make_pair(27, std::make_tuple(230, 224, 17)));
color_lookup_table.insert(make_pair(28, std::make_tuple(36, 51, 135)));
color_lookup_table.insert(make_pair(38, std::make_tuple(255, 0, 0)));
color_lookup_table.insert(make_pair(43, std::make_tuple(0, 255, 0)));
color_lookup_table.insert(make_pair(44, std::make_tuple(34, 139, 34)));
color_lookup_table.insert(make_pair(49, std::make_tuple(50, 205, 50)));
color_lookup_table.insert(make_pair(63, std::make_tuple(0, 0, 255)));
for (int i = 0 ; i < length; i++) {
auto it = color_lookup_table.find(edit_ptr[i]);
if (it != color_lookup_table.end()) {
rgb_image_buf[i * 3 + 0] = get<0>(it->second);
rgb_image_buf[i * 3 + 1] = get<1>(it->second);
rgb_image_buf[i * 3 + 2] = get<2>(it->second);
}
else {
rgb_image_buf[i * 3 + 0] = edit_ptr[i];
rgb_image_buf[i * 3 + 1] = edit_ptr[i];
rgb_image_buf[i * 3 + 2] = edit_ptr[i];
}
}
cv::Mat image;
Buffer2Mat_123(rgb_image_buf, out_dims[0], out_dims[1], 8*3, image);
cv::imshow("Image", image);
cv::waitKey(0);
}
The first picture is the image of SetInterpolationModeToNearestNeighbor;
The second and third are the images generated by SetInterpolationModeToLinear and SetInterpolationModeToCubic respectively: