{
  "id": 428871,
  "title": "😥Slice spacing is NOT consistent across different series",
  "url": "/competitions/rsna-2023-abdominal-trauma-detection/discussion/428871",
  "author_name": "JavaZero",
  "post_date": "2023-08-03T06:49:40.539000",
  "votes": 11,
  "comment_count": 2,
  "views": 0,
  "content": "<p>I have discovered that the slice spacing, or the distance between each consecutive slice, is not consistent across different series.</p>\n<p>To illustrate this issue, I have plotted the positions of the slices in several DICOM series. As shown in the plots, the distances between consecutive slices vary from series to series.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8314415%2F0f2e6c051c774f1baedaa057a9574cfa%2Foutput.png?generation=1691043881781238&amp;alt=media\" alt=\"\"></p>\n<blockquote>\n  <p>In fact many series have different the slice spacing</p>\n</blockquote>\n<p>For those who plan to work with 3D data, please be aware of this issue and consider it when pre-processing your data. You might need to resample your volumes to obtain consistent voxel sizes.</p>\n<hr>\n<p>You can try to solve this problem with the <a href=\"https://www.kaggle.com/datasets/jimmyisme1/monai-110\" target=\"_blank\">monai</a> library. <a href=\"https://docs.monai.io/en/stable/transforms.html#monai.transforms.Spacing\" target=\"_blank\">Doc</a></p>\n<pre><code> numpy  np\n torch\n monai.transforms  Spacing\n monai.data  ITKReader\n\nreader = ITKReader()\nimg, meta = reader.read()\n\nspacing_transform = Spacing(pixdim=(, , ), mode=)\n\nimg = spacing_transform(img)\n</code></pre>",
  "messages": [
    {
      "id": 2371539,
      "postDate": "2023-08-03T06:49:40.540Z",
      "content": "<p>I have discovered that the slice spacing, or the distance between each consecutive slice, is not consistent across different series.</p>\n<p>To illustrate this issue, I have plotted the positions of the slices in several DICOM series. As shown in the plots, the distances between consecutive slices vary from series to series.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8314415%2F0f2e6c051c774f1baedaa057a9574cfa%2Foutput.png?generation=1691043881781238&amp;alt=media\" alt=\"\"></p>\n<blockquote>\n  <p>In fact many series have different the slice spacing</p>\n</blockquote>\n<p>For those who plan to work with 3D data, please be aware of this issue and consider it when pre-processing your data. You might need to resample your volumes to obtain consistent voxel sizes.</p>\n<hr>\n<p>You can try to solve this problem with the <a href=\"https://www.kaggle.com/datasets/jimmyisme1/monai-110\" target=\"_blank\">monai</a> library. <a href=\"https://docs.monai.io/en/stable/transforms.html#monai.transforms.Spacing\" target=\"_blank\">Doc</a></p>\n<pre><code> numpy  np\n torch\n monai.transforms  Spacing\n monai.data  ITKReader\n\nreader = ITKReader()\nimg, meta = reader.read()\n\nspacing_transform = Spacing(pixdim=(, , ), mode=)\n\nimg = spacing_transform(img)\n</code></pre>",
      "rawMarkdown": "I have discovered that the slice spacing, or the distance between each consecutive slice, is not consistent across different series.\n\nTo illustrate this issue, I have plotted the positions of the slices in several DICOM series. As shown in the plots, the distances between consecutive slices vary from series to series.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8314415%2F0f2e6c051c774f1baedaa057a9574cfa%2Foutput.png?generation=1691043881781238&alt=media)\n\n> In fact many series have different the slice spacing\n\nFor those who plan to work with 3D data, please be aware of this issue and consider it when pre-processing your data. You might need to resample your volumes to obtain consistent voxel sizes.\n\n---\n\nYou can try to solve this problem with the [monai](https://www.kaggle.com/datasets/jimmyisme1/monai-110) library. [Doc](https://docs.monai.io/en/stable/transforms.html#monai.transforms.Spacing)\n\n```python\nimport numpy as np\nimport torch\nfrom monai.transforms import Spacing\nfrom monai.data import ITKReader\n\nreader = ITKReader()\nimg, meta = reader.read(\"/path/to/your/dicom/folder\")\n\nspacing_transform = Spacing(pixdim=(1.0, 1.0, 1.0), mode='bilinear')\n\nimg = spacing_transform(img)\n```",
      "votes": 11
    },
    {
      "id": 2449124,
      "postDate": "2023-09-21T03:06:32.060Z",
      "content": "<p>without external lib:</p>\n<pre><code> ():\n    info = ds.getPixelDataInfo()\n     info[] != :\n         RuntimeError()  \n    shape = [info[], info[]]\n    dtype = info[]\n    outarr = np.empty(shape, dtype=dtype)\n    ds.copyFrameData(index, outarr)\n     outarr\n\n\n ():\n    dcm_file = (glob(), key= x: (x.split()[-].split()[]))\n\n    \n     (dcm_file) &lt;= :\n        image = np.random.rand(,,)\n        dz, dy, dx = ,,\n         image, (dz, dy, dx)\n\n    \n     slice_range  :\n        slice_min = (dcm_file[].split()[-].split()[])\n        slice_max = (dcm_file[-].split()[-].split()[])+\n        slice_range=(slice_min, slice_max)\n\n    slice_min, slice_max = slice_range\n    sz0, szN = , \n\n    image = []\n     s  (slice_min, slice_max):\n        f = \n\n        \n        \n        \n        \n        \n           f:\n            ()\n            \n        \n\n        \n        \n        \n\n        dcm = dicomsdl.(f)\n        pixel_array = dicomsdl_to_numpy_image(dcm)\n         dcm.PixelRepresentation == :\n            bit_shift = dcm.BitsAllocated - dcm.BitsStored\n            dtype = pixel_array.dtype\n            pixel_array = (pixel_array &lt;&lt; bit_shift).astype(dtype) &gt;&gt; bit_shift\n\n        \n        pixel_array = pixel_array.astype(np.float32)\n        pixel_array = dcm.RescaleSlope * pixel_array + dcm.RescaleIntercept\n        xmin = dcm.WindowCenter--(dcm.WindowWidth-)* \n        xmax = dcm.WindowCenter-+(dcm.WindowWidth-)* \n        \n        \n        norm = pixel_array - xmin\n\n         dcm.PhotometricInterpretation == :\n            norm = -norm\n            \n\n        norm = norm / (xmax - xmin)\n        image.append(norm)\n\n    \n    dcm0 = dicomsdl.()\n    dcmN = dicomsdl.()\n    sx0, sy0, sz0 = dcm0.ImagePositionPatient\n    sxN, syN, szN = dcmN.ImagePositionPatient\n     szN &gt; sz0:\n        image = image[::-]\n\n    dx, dy = dcm0.PixelSpacing\n    dz = np.((szN - sz0) / (slice_max - slice_min-))\n\n    image = np.stack(image)\n    image_tag = dotdict(\n        spacing = (dz,dy,dx),\n        slice_min = slice_min,\n        slice_max = slice_max,\n    )\n     image, image_tag\n\n\nUSAGE:\n              ....\n        dcm_dir = \n        image, image_tag = load_dicomsdl_dir(dcm_dir, slice_range=(slice_min,slice_max))\n        image = np.clip(image,,)\n        l,h,w = image.shape\n        dz,dh,dy = image_tag.spacing\n\n        image = torch.from_numpy(image)\n        image = F.interpolate(\n            image.unsqueeze().unsqueeze(),\n            size=[(l*dz/dy),h,w ], \n            mode=,\n            align_corners=,\n        ).squeeze().squeeze()\n        image = image.data.numpy()\n</code></pre>\n<p>while i use dicomsdl, you can use pydicom instead(slower)</p>\n<p>example results</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Ff851b1aeea74c26977643553cdccd585%2FSelection_999(3323).png?generation=1695265475607941&amp;alt=media\" alt=\"\"></p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Fc4df672c587cc9344f2cb12cc8f0a680%2FSelection_999(3324).png?generation=1695265531290491&amp;alt=media\" alt=\"\"></p>",
      "rawMarkdown": "without external lib:\n```\n\ndef dicomsdl_to_numpy_image(ds, index=0):\n\tinfo = ds.getPixelDataInfo()\n\tif info['SamplesPerPixel'] != 1:\n\t\traise RuntimeError('SamplesPerPixel != 1')  # number of separate planes in this image\n\tshape = [info['Rows'], info['Cols']]\n\tdtype = info['dtype']\n\toutarr = np.empty(shape, dtype=dtype)\n\tds.copyFrameData(index, outarr)\n\treturn outarr\n\n\ndef load_dicomsdl_dir(dcm_dir, slice_range=None):\n\tdcm_file = sorted(glob(f'{dcm_dir}/*.dcm'), key=lambda x: int(x.split('/')[-1].split('.')[0]))\n\n\t# fake some slice so that it won't cause error  in kaggle dummy test (only single slice) ....\n\tif len(dcm_file) <= 1:\n\t\timage = np.random.rand(16,256,256)\n\t\tdz, dy, dx = 1,1,1\n\t\treturn image, (dz, dy, dx)\n\n\t#----------------------------------------------------------\n\tif slice_range is None:\n\t\tslice_min = int(dcm_file[0].split('/')[-1].split('.')[0])\n\t\tslice_max = int(dcm_file[-1].split('/')[-1].split('.')[0])+1\n\t\tslice_range=(slice_min, slice_max)\n\n\tslice_min, slice_max = slice_range\n\tsz0, szN = None, None\n\n\timage = []\n\tfor s in range(slice_min, slice_max):\n\t\tf = f'{dcm_dir}/{s}.dcm'\n\n\t\t# https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection/discussion/435815\n\t\t# Single corrupt image in the hidden test set\n\t\t# test_images/3124/5842/514.dcm\n\t\t#print(f)\n\t\t#if '/11597/17580/13.dcm' in f:\n\t\tif '/3124/5842/514.dcm' in f:\n\t\t\tprint('SKIPPING ERROR dcm !!!')\n\t\t\tcontinue\n\t\t#-------------------------------------------------------------------------------------------\n\n\t\t#dcm = pydicom.read_file(f)\n\t\t#m = dcm.pixel_array\n\t\t#m = standardize_pixel_array(dcm)\n\n\t\tdcm = dicomsdl.open(f)\n\t\tpixel_array = dicomsdl_to_numpy_image(dcm)\n\t\tif dcm.PixelRepresentation == 1:\n\t\t\tbit_shift = dcm.BitsAllocated - dcm.BitsStored\n\t\t\tdtype = pixel_array.dtype\n\t\t\tpixel_array = (pixel_array << bit_shift).astype(dtype) >> bit_shift\n\n\t\t#processing\n\t\tpixel_array = pixel_array.astype(np.float32)\n\t\tpixel_array = dcm.RescaleSlope * pixel_array + dcm.RescaleIntercept\n\t\txmin = dcm.WindowCenter-0.5-(dcm.WindowWidth-1)* 0.5\n\t\txmax = dcm.WindowCenter-0.5+(dcm.WindowWidth-1)* 0.5\n\t\t#norm = np.empty_like(pixel_array, dtype=np.uint8)\n\t\t#dicomsdl.util.convert_to_uint8(pixel_array, norm, xmin, xmax)\n\t\tnorm = pixel_array - xmin\n\n\t\tif dcm.PhotometricInterpretation == 'MONOCHROME1':\n\t\t\tnorm = -norm\n\t\t\t#raise NotImplementedError\n\n\t\tnorm = norm / (xmax - xmin)\n\t\timage.append(norm)\n\n\t#check inversion\n\tdcm0 = dicomsdl.open(f'{dcm_dir}/{slice_min}.dcm')\n\tdcmN = dicomsdl.open(f'{dcm_dir}/{slice_max-1}.dcm')\n\tsx0, sy0, sz0 = dcm0.ImagePositionPatient\n\tsxN, syN, szN = dcmN.ImagePositionPatient\n\tif szN > sz0:\n\t\timage = image[::-1]\n\n\tdx, dy = dcm0.PixelSpacing\n\tdz = np.abs((szN - sz0) / (slice_max - slice_min-1))\n\n\timage = np.stack(image)\n\timage_tag = dotdict(\n\t\tspacing = (dz,dy,dx),\n\t\tslice_min = slice_min,\n\t\tslice_max = slice_max,\n\t)\n\treturn image, image_tag\n\n\nUSAGE:\n              ....\n\t\tdcm_dir = f'{train_images_dir}/{patient_id}/{series_id}'\n\t\timage, image_tag = load_dicomsdl_dir(dcm_dir, slice_range=(slice_min,slice_max))\n\t\timage = np.clip(image,0,1)\n\t\tl,h,w = image.shape\n\t\tdz,dh,dy = image_tag.spacing\n\n\t\timage = torch.from_numpy(image)\n\t\timage = F.interpolate(\n\t\t\timage.unsqueeze(0).unsqueeze(0),\n\t\t\tsize=[int(l*dz/dy),h,w ], #change dz spacing same as dy(=dx)\n\t\t\tmode='trilinear',\n\t\t\talign_corners=False,\n\t\t).squeeze(0).squeeze(0)\n\t\timage = image.data.numpy()\n\n\n```\nwhile i use dicomsdl, you can use pydicom instead(slower)\n\nexample results\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Ff851b1aeea74c26977643553cdccd585%2FSelection_999(3323).png?generation=1695265475607941&alt=media)\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Fc4df672c587cc9344f2cb12cc8f0a680%2FSelection_999(3324).png?generation=1695265531290491&alt=media)",
      "votes": 3
    },
    {
      "id": 2447248,
      "postDate": "2023-09-20T00:15:50.127Z",
      "rawMarkdown": "",
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 2449124,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2023-09-21T03:06:32.060000",
      "content": "<p>without external lib:</p>\n<pre><code> ():\n    info = ds.getPixelDataInfo()\n     info[] != :\n         RuntimeError()  \n    shape = [info[], info[]]\n    dtype = info[]\n    outarr = np.empty(shape, dtype=dtype)\n    ds.copyFrameData(index, outarr)\n     outarr\n\n\n ():\n    dcm_file = (glob(), key= x: (x.split()[-].split()[]))\n\n    \n     (dcm_file) &lt;= :\n        image = np.random.rand(,,)\n        dz, dy, dx = ,,\n         image, (dz, dy, dx)\n\n    \n     slice_range  :\n        slice_min = (dcm_file[].split()[-].split()[])\n        slice_max = (dcm_file[-].split()[-].split()[])+\n        slice_range=(slice_min, slice_max)\n\n    slice_min, slice_max = slice_range\n    sz0, szN = , \n\n    image = []\n     s  (slice_min, slice_max):\n        f = \n\n        \n        \n        \n        \n        \n           f:\n            ()\n            \n        \n\n        \n        \n        \n\n        dcm = dicomsdl.(f)\n        pixel_array = dicomsdl_to_numpy_image(dcm)\n         dcm.PixelRepresentation == :\n            bit_shift = dcm.BitsAllocated - dcm.BitsStored\n            dtype = pixel_array.dtype\n            pixel_array = (pixel_array &lt;&lt; bit_shift).astype(dtype) &gt;&gt; bit_shift\n\n        \n        pixel_array = pixel_array.astype(np.float32)\n        pixel_array = dcm.RescaleSlope * pixel_array + dcm.RescaleIntercept\n        xmin = dcm.WindowCenter--(dcm.WindowWidth-)* \n        xmax = dcm.WindowCenter-+(dcm.WindowWidth-)* \n        \n        \n        norm = pixel_array - xmin\n\n         dcm.PhotometricInterpretation == :\n            norm = -norm\n            \n\n        norm = norm / (xmax - xmin)\n        image.append(norm)\n\n    \n    dcm0 = dicomsdl.()\n    dcmN = dicomsdl.()\n    sx0, sy0, sz0 = dcm0.ImagePositionPatient\n    sxN, syN, szN = dcmN.ImagePositionPatient\n     szN &gt; sz0:\n        image = image[::-]\n\n    dx, dy = dcm0.PixelSpacing\n    dz = np.((szN - sz0) / (slice_max - slice_min-))\n\n    image = np.stack(image)\n    image_tag = dotdict(\n        spacing = (dz,dy,dx),\n        slice_min = slice_min,\n        slice_max = slice_max,\n    )\n     image, image_tag\n\n\nUSAGE:\n              ....\n        dcm_dir = \n        image, image_tag = load_dicomsdl_dir(dcm_dir, slice_range=(slice_min,slice_max))\n        image = np.clip(image,,)\n        l,h,w = image.shape\n        dz,dh,dy = image_tag.spacing\n\n        image = torch.from_numpy(image)\n        image = F.interpolate(\n            image.unsqueeze().unsqueeze(),\n            size=[(l*dz/dy),h,w ], \n            mode=,\n            align_corners=,\n        ).squeeze().squeeze()\n        image = image.data.numpy()\n</code></pre>\n<p>while i use dicomsdl, you can use pydicom instead(slower)</p>\n<p>example results</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Ff851b1aeea74c26977643553cdccd585%2FSelection_999(3323).png?generation=1695265475607941&amp;alt=media\" alt=\"\"></p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Fc4df672c587cc9344f2cb12cc8f0a680%2FSelection_999(3324).png?generation=1695265531290491&amp;alt=media\" alt=\"\"></p>",
      "votes": 3,
      "replies": []
    },
    {
      "id": 2447248,
      "author_name": "",
      "author_url": "",
      "post_date": "2023-09-20T00:15:50.127000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "2371539": "I have discovered that the slice spacing, or the distance between each consecutive slice, is not consistent across different series.\n\nTo illustrate this issue, I have plotted the positions of the slices in several DICOM series. As shown in the plots, the distances between consecutive slices vary from series to series.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8314415%2F0f2e6c051c774f1baedaa057a9574cfa%2Foutput.png?generation=1691043881781238&alt=media)\n\n> In fact many series have different the slice spacing\n\nFor those who plan to work with 3D data, please be aware of this issue and consider it when pre-processing your data. You might need to resample your volumes to obtain consistent voxel sizes.\n\n---\n\nYou can try to solve this problem with the [monai](https://www.kaggle.com/datasets/jimmyisme1/monai-110) library. [Doc](https://docs.monai.io/en/stable/transforms.html#monai.transforms.Spacing)\n\n```python\nimport numpy as np\nimport torch\nfrom monai.transforms import Spacing\nfrom monai.data import ITKReader\n\nreader = ITKReader()\nimg, meta = reader.read(\"/path/to/your/dicom/folder\")\n\nspacing_transform = Spacing(pixdim=(1.0, 1.0, 1.0), mode='bilinear')\n\nimg = spacing_transform(img)\n```",
    "2449124": "without external lib:\n```\n\ndef dicomsdl_to_numpy_image(ds, index=0):\n\tinfo = ds.getPixelDataInfo()\n\tif info['SamplesPerPixel'] != 1:\n\t\traise RuntimeError('SamplesPerPixel != 1')  # number of separate planes in this image\n\tshape = [info['Rows'], info['Cols']]\n\tdtype = info['dtype']\n\toutarr = np.empty(shape, dtype=dtype)\n\tds.copyFrameData(index, outarr)\n\treturn outarr\n\n\ndef load_dicomsdl_dir(dcm_dir, slice_range=None):\n\tdcm_file = sorted(glob(f'{dcm_dir}/*.dcm'), key=lambda x: int(x.split('/')[-1].split('.')[0]))\n\n\t# fake some slice so that it won't cause error  in kaggle dummy test (only single slice) ....\n\tif len(dcm_file) <= 1:\n\t\timage = np.random.rand(16,256,256)\n\t\tdz, dy, dx = 1,1,1\n\t\treturn image, (dz, dy, dx)\n\n\t#----------------------------------------------------------\n\tif slice_range is None:\n\t\tslice_min = int(dcm_file[0].split('/')[-1].split('.')[0])\n\t\tslice_max = int(dcm_file[-1].split('/')[-1].split('.')[0])+1\n\t\tslice_range=(slice_min, slice_max)\n\n\tslice_min, slice_max = slice_range\n\tsz0, szN = None, None\n\n\timage = []\n\tfor s in range(slice_min, slice_max):\n\t\tf = f'{dcm_dir}/{s}.dcm'\n\n\t\t# https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection/discussion/435815\n\t\t# Single corrupt image in the hidden test set\n\t\t# test_images/3124/5842/514.dcm\n\t\t#print(f)\n\t\t#if '/11597/17580/13.dcm' in f:\n\t\tif '/3124/5842/514.dcm' in f:\n\t\t\tprint('SKIPPING ERROR dcm !!!')\n\t\t\tcontinue\n\t\t#-------------------------------------------------------------------------------------------\n\n\t\t#dcm = pydicom.read_file(f)\n\t\t#m = dcm.pixel_array\n\t\t#m = standardize_pixel_array(dcm)\n\n\t\tdcm = dicomsdl.open(f)\n\t\tpixel_array = dicomsdl_to_numpy_image(dcm)\n\t\tif dcm.PixelRepresentation == 1:\n\t\t\tbit_shift = dcm.BitsAllocated - dcm.BitsStored\n\t\t\tdtype = pixel_array.dtype\n\t\t\tpixel_array = (pixel_array << bit_shift).astype(dtype) >> bit_shift\n\n\t\t#processing\n\t\tpixel_array = pixel_array.astype(np.float32)\n\t\tpixel_array = dcm.RescaleSlope * pixel_array + dcm.RescaleIntercept\n\t\txmin = dcm.WindowCenter-0.5-(dcm.WindowWidth-1)* 0.5\n\t\txmax = dcm.WindowCenter-0.5+(dcm.WindowWidth-1)* 0.5\n\t\t#norm = np.empty_like(pixel_array, dtype=np.uint8)\n\t\t#dicomsdl.util.convert_to_uint8(pixel_array, norm, xmin, xmax)\n\t\tnorm = pixel_array - xmin\n\n\t\tif dcm.PhotometricInterpretation == 'MONOCHROME1':\n\t\t\tnorm = -norm\n\t\t\t#raise NotImplementedError\n\n\t\tnorm = norm / (xmax - xmin)\n\t\timage.append(norm)\n\n\t#check inversion\n\tdcm0 = dicomsdl.open(f'{dcm_dir}/{slice_min}.dcm')\n\tdcmN = dicomsdl.open(f'{dcm_dir}/{slice_max-1}.dcm')\n\tsx0, sy0, sz0 = dcm0.ImagePositionPatient\n\tsxN, syN, szN = dcmN.ImagePositionPatient\n\tif szN > sz0:\n\t\timage = image[::-1]\n\n\tdx, dy = dcm0.PixelSpacing\n\tdz = np.abs((szN - sz0) / (slice_max - slice_min-1))\n\n\timage = np.stack(image)\n\timage_tag = dotdict(\n\t\tspacing = (dz,dy,dx),\n\t\tslice_min = slice_min,\n\t\tslice_max = slice_max,\n\t)\n\treturn image, image_tag\n\n\nUSAGE:\n              ....\n\t\tdcm_dir = f'{train_images_dir}/{patient_id}/{series_id}'\n\t\timage, image_tag = load_dicomsdl_dir(dcm_dir, slice_range=(slice_min,slice_max))\n\t\timage = np.clip(image,0,1)\n\t\tl,h,w = image.shape\n\t\tdz,dh,dy = image_tag.spacing\n\n\t\timage = torch.from_numpy(image)\n\t\timage = F.interpolate(\n\t\t\timage.unsqueeze(0).unsqueeze(0),\n\t\t\tsize=[int(l*dz/dy),h,w ], #change dz spacing same as dy(=dx)\n\t\t\tmode='trilinear',\n\t\t\talign_corners=False,\n\t\t).squeeze(0).squeeze(0)\n\t\timage = image.data.numpy()\n\n\n```\nwhile i use dicomsdl, you can use pydicom instead(slower)\n\nexample results\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Ff851b1aeea74c26977643553cdccd585%2FSelection_999(3323).png?generation=1695265475607941&alt=media)\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F113660%2Fc4df672c587cc9344f2cb12cc8f0a680%2FSelection_999(3324).png?generation=1695265531290491&alt=media)",
    "2447248": ""
  }
}