VTK例子--使用vtkNIFTIImageReader读unsigned char的nii.gz文件并使用vtkImageReslice切面显示RGB

功能

        对掩膜数据进行MPR的操作,获取切面图像,并转换为RGB图像,使用OpenCV展示;

涉及功能点:

        1.使用vtkNIFTIImageReader类读取nii.gz文件;

        2.使用vtkImageReslice类获取切面图像;

        3.二维的unsigned char数组转换为cv::Mat;

        如何使用vtkImageReslice类获取切面图像,参考笔记:

VTK笔记-计算MPR切面-vtkImageReslice类_黑山老妖的博客的博客-CSDN博客_vtk 切面MPRMPR(Multi-planar Reformation),多平面重建;多平面重建是将扫描范围内所有的轴位图像叠加起来,再对某些标线标定的重组线所指定的组织进行冠状位、矢状位、任意角度斜位图像重组。MPR的优点1.能任意产生新的断层图像,而无需重复扫描;2.原图像的密度值被忠实保持到了结果图像上。3.曲面重组能在一副图像里展开显示弯曲物体的全长。MPR的缺点1.难以表达复杂的空间结构;2.曲面重组易造成假阳性;...https://blog.csdn.net/liushao1031177/article/details/118946205详细代码如下:

// 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);
}

第一张图是SetInterpolationModeToNearestNeighbor的图像;

第二张和第三张分别是SetInterpolationModeToLinear、SetInterpolationModeToCubic生成的图像:

猜你喜欢

转载自blog.csdn.net/liushao1031177/article/details/124847587