You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SimpleITK手动修改3D图像像素后无效果的技术求助

SimpleITK C#: Modifying Pixel Buffer via GetBuffer Doesn't Update Output Image

Let's break down why your code isn't working and fix it step by step:

Key Issues in Your Code

  1. Incorrect Pixel Index Calculation
    Your formula for accessing 3D pixels in the 1D buffer is wrong. SimpleITK uses x as the fastest axis (size[0] = x-dimension, size[1] = y-dimension, size[2] = z-dimension). The correct index formula should map the 3D coordinates to the 1D buffer properly, but your current calculation points to invalid or unrelated memory locations—meaning you weren't actually modifying the pixels you intended.

  2. Unnecessary ImportImageFilter
    When you call GetBufferAsUInt8(), you're getting a direct pointer to the original image's underlying memory buffer (assuming the image is contiguous, which it is by default). Modifying this buffer directly changes the original input image, so re-importing the buffer with ImportImageFilter is redundant and can cause memory handling confusion.

Fixed Code

Here's the corrected version of your code with clear explanations:

using itk.simple;

class Program
{
    static void Main(string[] args)
    {
        string filepath = "C:\\Users\\pragun\\Desktop\\Selected Data\\stack.mhd";
        ImageFileReader readerx = new ImageFileReader();
        readerx.SetFileName(filepath);
        Image input = readerx.Execute();
        
        // Cast to UInt8 for byte-level buffer access
        input = SimpleITK.Cast(input, PixelIDValueEnum.sitkUInt8);
        
        VectorUInt32 size = input.GetSize();
        VectorDouble spacing = input.GetSpacing();
        
        Console.WriteLine($"Image Size: X={size[0]}, Y={size[1]}, Z={size[2]}");
        
        // Get direct pointer to the image's pixel buffer
        IntPtr buffer = input.GetBufferAsUInt8();
        
        unsafe
        {
            byte* bufferPtr = (byte*)buffer.ToPointer();
            
            // Iterate through all 3D pixels with the correct index formula
            for (int k = 0; k < size[2]; k++) // Z-axis (slowest to iterate)
            {
                for (int j = 0; j < size[1]; j++) // Y-axis
                {
                    for (int i = 0; i < size[0]; i++) // X-axis (fastest to iterate)
                    {
                        // Correct 3D to 1D index mapping
                        int index = i + j * (int)size[0] + k * (int)size[0] * (int)size[1];
                        bufferPtr[index] = 255; // Set every pixel to white
                    }
                }
            }
        }
        
        // No need for ImportImageFilter—use the modified original image directly
        SimpleITK.Show(input);
        
        // Optional: Save the modified image to file
        ImageFileWriter writer = new ImageFileWriter();
        writer.SetFileName("modified_stack.mhd");
        writer.Execute(input);
    }
}

Additional Notes

  • Enable Unsafe Code: Don't forget to enable unsafe code in your project settings (right-click project → Properties → Build → Check "Allow unsafe code").
  • Image Contiguity: If your image ever becomes non-contiguous (rare for standard workflows), create a contiguous copy first with:
    input = SimpleITK.MakeImage(input.GetSize(), input);
    
  • Unsafe Code Alternative: If you prefer to avoid unsafe code, use GetPixelAsUInt8() and SetPixelAsUInt8() (note: this is slower for large 3D images):
    for (int k = 0; k < size[2]; k++)
    {
        for (int j = 0; j < size[1]; j++)
        {
            for (int i = 0; i < size[0]; i++)
            {
                input.SetPixelAsUInt8(new[] { (uint)i, (uint)j, (uint)k }, 255);
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者Tompel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:45:02