VTK の例 -- vtkNIFTIImageReader を使用して unsigned char nii.gz ファイルを読み取り、vtkImageReslice を使用して RGB を表示します

関数

        マスクデータに対してMPR演算を実行し、スライス画像を取得してRGB画像に変換し、OpenCVを使用して表示します。

関係する機能ポイント:

        1. vtkNIFTIImageReader クラスを使用して nii.gz ファイルを読み取ります。

        2. vtkImageReslice クラスを使用して、スライスされた画像を取得します。

        3. 2 次元の unsigned char 配列を cv::Mat に変換します。

        vtkImageReslice クラスを使用してスライスされた画像を取得する方法は、次のメモを参照してください。

VTK Notes - MPR スライスの計算 - vtkImageReslice クラス を使用 MPR のメリット 1. スキャンを繰り返すことなく任意に新しい断層画像を生成できる; 2. 元の画像の濃度値が忠実に維持された画像が得られる。3. 曲面再構成により、曲面オブジェクトの全長を 1 つの画像に表示できます。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 のイメージです。

2 番目と 3 番目は、それぞれ SetInterpolationModeToLinear と SetInterpolationModeToCubic によって生成されたイメージです。

おすすめ

転載: blog.csdn.net/liushao1031177/article/details/124847587