{
  "id": 679248,
  "title": "8th-place-solution",
  "url": "/competitions/vesuvius-challenge-surface-detection/writeups/8th-place-solution",
  "author_name": "",
  "post_date": "2026-02-28T05:55:19.580Z",
  "votes": 13,
  "comment_count": 4,
  "views": 0,
  "content": "<p>Thanks to the organizers for hosting this technically challenging and topology-sensitive competition, and congratulations to all prize-winning teams.</p>\n<h2>One-line summary:</h2>\n<p>Multi-scale nnUNetResEncUNetL ensemble + mean fusion + probability diffusion + direction-aware adaptive hysteresis.</p>\n<h2>Models.</h2>\n<p>The backbone is nnUNetResEncUNetL, without architectural modification. Three models were trained with different patch sizes, focusing on MedialSurfaceRecall: patch 224 (500 epochs), patch 256 (500 epochs), and patch 288 (500 epochs). Different patch sizes provide complementary receptive fields, balancing local surface precision and global continuity.</p>\n<h2>Inference &amp; fusion.</h2>\n<p>Inference followed the standard nnUNet sliding-window pipeline (step_size = 0.9). Patch 224 and 256 used mirroring TTA, while patch 288 did not due to inference speed constraints. The final prediction was obtained by direct mean fusion of the three probability maps, without logit weighting, which showed more stable leaderboard behavior.</p>\n<h2>Post-processing (key part).</h2>\n<p>Most performance gains came from post-processing. First, gradient anisotropic diffusion was applied twice to the fused probability map (conductance = 2.0, time_step = 0.04) to smooth fragmented responses while preserving sharp surface transitions in probability space.\nSecond, adaptive hysteresis thresholding with directional morphology was applied. Parameters were T_low = 0.50, T_high = 0.90, z_radius = 1, xy_radius = 0, and min_size = 100. Voxels above T_high define high-confidence surface cores, while voxels between T_low and T_high are included only if connected to the core. Morphological connectivity is restricted to the z direction to reflect the thin layered structure of the scroll surface and prevent lateral over-expansion, followed by removal of small isolated components.</p>\n<p>A lighter diffusion variant (single iteration, conductance = 1.5, time_step = 0.03) slightly improved private performance (up to 0.618) but reduced the public score (0.595 → 0.593). Compared to using adaptive hysteresis alone, diffusion improved local validation by ~0.005, although its public score was slightly worse. We therefore selected the stronger diffusion setting, trusting the local evaluation and prioritizing overall stability.</p>\n<p>Overall, the solution avoids complex architectural tricks and relies on scale diversity, stable mean ensembling, probability-space smoothing, and direction-aware adaptive thresholding.</p>\n<p>Due to the Chinese New Year holiday, I was not able to devote much time to the competition during the final two weeks; given that, I am very satisfied with the final ranking. Thanks again to the organizers for this unique and inspiring challenge.</p>\n<p>The inference notebook is <a href=\"https://www.kaggle.com/code/lingyundev/notebook686f6dd4fe\" target=\"_blank\">here</a>.\nCode is <a href=\"https://github.com/LingYunGit/SurfaceDetection_8th_Solution\" target=\"_blank\">here</a>.</p>",
  "messages": [
    {
      "id": "3415066",
      "postDate": "02/28/2026 05:53:39",
      "content": "<p>Thanks to the organizers for hosting this technically challenging and topology-sensitive competition, and congratulations to all prize-winning teams.</p>\n<h2>One-line summary:</h2>\n<p>Multi-scale nnUNetResEncUNetL ensemble + mean fusion + probability diffusion + direction-aware adaptive hysteresis.</p>\n<h2>Models.</h2>\n<p>The backbone is nnUNetResEncUNetL, without architectural modification. Three models were trained with different patch sizes, focusing on MedialSurfaceRecall: patch 224 (500 epochs), patch 256 (500 epochs), and patch 288 (500 epochs). Different patch sizes provide complementary receptive fields, balancing local surface precision and global continuity.</p>\n<h2>Inference &amp; fusion.</h2>\n<p>Inference followed the standard nnUNet sliding-window pipeline (step_size = 0.9). Patch 224 and 256 used mirroring TTA, while patch 288 did not due to inference speed constraints. The final prediction was obtained by direct mean fusion of the three probability maps, without logit weighting, which showed more stable leaderboard behavior.</p>\n<h2>Post-processing (key part).</h2>\n<p>Most performance gains came from post-processing. First, gradient anisotropic diffusion was applied twice to the fused probability map (conductance = 2.0, time_step = 0.04) to smooth fragmented responses while preserving sharp surface transitions in probability space.\nSecond, adaptive hysteresis thresholding with directional morphology was applied. Parameters were T_low = 0.50, T_high = 0.90, z_radius = 1, xy_radius = 0, and min_size = 100. Voxels above T_high define high-confidence surface cores, while voxels between T_low and T_high are included only if connected to the core. Morphological connectivity is restricted to the z direction to reflect the thin layered structure of the scroll surface and prevent lateral over-expansion, followed by removal of small isolated components.</p>\n<p>A lighter diffusion variant (single iteration, conductance = 1.5, time_step = 0.03) slightly improved private performance (up to 0.618) but reduced the public score (0.595 → 0.593). Compared to using adaptive hysteresis alone, diffusion improved local validation by ~0.005, although its public score was slightly worse. We therefore selected the stronger diffusion setting, trusting the local evaluation and prioritizing overall stability.</p>\n<p>Overall, the solution avoids complex architectural tricks and relies on scale diversity, stable mean ensembling, probability-space smoothing, and direction-aware adaptive thresholding.</p>\n<p>Due to the Chinese New Year holiday, I was not able to devote much time to the competition during the final two weeks; given that, I am very satisfied with the final ranking. Thanks again to the organizers for this unique and inspiring challenge.</p>\n<p>The inference notebook is <a href=\"https://www.kaggle.com/code/lingyundev/notebook686f6dd4fe\" target=\"_blank\">here</a>.\nCode is <a href=\"https://github.com/LingYunGit/SurfaceDetection_8th_Solution\" target=\"_blank\">here</a>.</p>",
      "rawMarkdown": "Thanks to the organizers for hosting this technically challenging and topology-sensitive competition, and congratulations to all prize-winning teams.\n\n## One-line summary:\nMulti-scale nnUNetResEncUNetL ensemble + mean fusion + probability diffusion + direction-aware adaptive hysteresis.\n\n## Models.\nThe backbone is nnUNetResEncUNetL, without architectural modification. Three models were trained with different patch sizes, focusing on MedialSurfaceRecall: patch 224 (500 epochs), patch 256 (500 epochs), and patch 288 (500 epochs). Different patch sizes provide complementary receptive fields, balancing local surface precision and global continuity.\n\n## Inference & fusion.\nInference followed the standard nnUNet sliding-window pipeline (step_size = 0.9). Patch 224 and 256 used mirroring TTA, while patch 288 did not due to inference speed constraints. The final prediction was obtained by direct mean fusion of the three probability maps, without logit weighting, which showed more stable leaderboard behavior.\n\n## Post-processing (key part).\nMost performance gains came from post-processing. First, gradient anisotropic diffusion was applied twice to the fused probability map (conductance = 2.0, time_step = 0.04) to smooth fragmented responses while preserving sharp surface transitions in probability space.\nSecond, adaptive hysteresis thresholding with directional morphology was applied. Parameters were T_low = 0.50, T_high = 0.90, z_radius = 1, xy_radius = 0, and min_size = 100. Voxels above T_high define high-confidence surface cores, while voxels between T_low and T_high are included only if connected to the core. Morphological connectivity is restricted to the z direction to reflect the thin layered structure of the scroll surface and prevent lateral over-expansion, followed by removal of small isolated components.\n\nA lighter diffusion variant (single iteration, conductance = 1.5, time_step = 0.03) slightly improved private performance (up to 0.618) but reduced the public score (0.595 → 0.593). Compared to using adaptive hysteresis alone, diffusion improved local validation by ~0.005, although its public score was slightly worse. We therefore selected the stronger diffusion setting, trusting the local evaluation and prioritizing overall stability.\n\nOverall, the solution avoids complex architectural tricks and relies on scale diversity, stable mean ensembling, probability-space smoothing, and direction-aware adaptive thresholding.\n\nDue to the Chinese New Year holiday, I was not able to devote much time to the competition during the final two weeks; given that, I am very satisfied with the final ranking. Thanks again to the organizers for this unique and inspiring challenge.\n\nThe inference notebook is [here](https://www.kaggle.com/code/lingyundev/notebook686f6dd4fe).\nCode is [here](https://github.com/LingYunGit/SurfaceDetection_8th_Solution).",
      "votes": null
    },
    {
      "id": "3415214",
      "postDate": "02/28/2026 12:30:26",
      "content": "<p>Interesting. I didn't know about \"gradient anisotropic diffusion\".</p>\n<p>Is it different from anisotropic diffusion as in wikipedia <a href=\"https://en.wikipedia.org/wiki/Anisotropic_diffusion\" target=\"_blank\">https://en.wikipedia.org/wiki/Anisotropic_diffusion</a> ? </p>\n<p>You made me search a bit, and I saw on wikipedia that anisotropic diffusion is a generalization of Gaussian smoothing. I used the latter, I wish I knew about the more general form. </p>\n<p>Further search makes em wonder about which implementation you used. Found some C++ ones, and this python one <a href=\"https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json\" target=\"_blank\">https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json</a></p>",
      "rawMarkdown": "Interesting. I didn't know about \"gradient anisotropic diffusion\".\n\nIs it different from anisotropic diffusion as in wikipedia https://en.wikipedia.org/wiki/Anisotropic_diffusion ? \n\nYou made me search a bit, and I saw on wikipedia that anisotropic diffusion is a generalization of Gaussian smoothing. I used the latter, I wish I knew about the more general form. \n\nFurther search makes em wonder about which implementation you used. Found some C++ ones, and this python one https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json",
      "votes": null
    },
    {
      "id": "3415247",
      "postDate": "02/28/2026 14:07:15",
      "content": "<p>Yes, it is closely related to the anisotropic diffusion described on Wikipedia (Perona–Malik). By “gradient anisotropic diffusion”, I simply mean that the diffusion strength is controlled by the local gradient magnitude, so smoothing is suppressed across strong edges and encouraged in flat regions, unlike Gaussian smoothing.</p>\n<p>The main difference in my usage is that diffusion is applied to the model output probability map, not to the raw image. This helps smooth fragmented responses while preserving thin surface boundaries. The implementation is equivalent in behavior to ITK / SimpleITK’s GradientAnisotropicDiffusionImageFilter.</p>",
      "rawMarkdown": "Yes, it is closely related to the anisotropic diffusion described on Wikipedia (Perona–Malik). By “gradient anisotropic diffusion”, I simply mean that the diffusion strength is controlled by the local gradient magnitude, so smoothing is suppressed across strong edges and encouraged in flat regions, unlike Gaussian smoothing.\n\nThe main difference in my usage is that diffusion is applied to the model output probability map, not to the raw image. This helps smooth fragmented responses while preserving thin surface boundaries. The implementation is equivalent in behavior to ITK / SimpleITK’s GradientAnisotropicDiffusionImageFilter.",
      "votes": null
    },
    {
      "id": "3415255",
      "postDate": "02/28/2026 14:18:57",
      "content": "<p>Thanks, learned something from you.</p>",
      "rawMarkdown": "Thanks, learned something from you.",
      "votes": null
    },
    {
      "id": "3415524",
      "postDate": "03/01/2026 01:13:31",
      "content": "<p>there's another python version here <a href=\"https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py\" target=\"_blank\">https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py</a></p>\n<p>that a number of teams appear to have used , if you're looking for one in python . </p>",
      "rawMarkdown": "there's another python version here https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py\n\nthat a number of teams appear to have used , if you're looking for one in python .",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 3415214,
      "author_name": "cpmpml",
      "author_url": "",
      "post_date": "02/28/2026 12:30:26",
      "content": "<p>Interesting. I didn't know about \"gradient anisotropic diffusion\".</p>\n<p>Is it different from anisotropic diffusion as in wikipedia <a href=\"https://en.wikipedia.org/wiki/Anisotropic_diffusion\" target=\"_blank\">https://en.wikipedia.org/wiki/Anisotropic_diffusion</a> ? </p>\n<p>You made me search a bit, and I saw on wikipedia that anisotropic diffusion is a generalization of Gaussian smoothing. I used the latter, I wish I knew about the more general form. </p>\n<p>Further search makes em wonder about which implementation you used. Found some C++ ones, and this python one <a href=\"https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json\" target=\"_blank\">https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json</a></p>",
      "votes": null,
      "replies": [
        {
          "id": 3415247,
          "author_name": "lingyundev",
          "author_url": "",
          "post_date": "02/28/2026 14:07:15",
          "content": "<p>Yes, it is closely related to the anisotropic diffusion described on Wikipedia (Perona–Malik). By “gradient anisotropic diffusion”, I simply mean that the diffusion strength is controlled by the local gradient magnitude, so smoothing is suppressed across strong edges and encouraged in flat regions, unlike Gaussian smoothing.</p>\n<p>The main difference in my usage is that diffusion is applied to the model output probability map, not to the raw image. This helps smooth fragmented responses while preserving thin surface boundaries. The implementation is equivalent in behavior to ITK / SimpleITK’s GradientAnisotropicDiffusionImageFilter.</p>",
          "votes": null,
          "replies": [
            {
              "id": 3415255,
              "author_name": "cpmpml",
              "author_url": "",
              "post_date": "02/28/2026 14:18:57",
              "content": "<p>Thanks, learned something from you.</p>",
              "votes": null,
              "replies": []
            }
          ]
        },
        {
          "id": 3415524,
          "author_name": "seanjohnsonsp",
          "author_url": "",
          "post_date": "03/01/2026 01:13:31",
          "content": "<p>there's another python version here <a href=\"https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py\" target=\"_blank\">https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py</a></p>\n<p>that a number of teams appear to have used , if you're looking for one in python . </p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "3415066": "Thanks to the organizers for hosting this technically challenging and topology-sensitive competition, and congratulations to all prize-winning teams.\n\n## One-line summary:\nMulti-scale nnUNetResEncUNetL ensemble + mean fusion + probability diffusion + direction-aware adaptive hysteresis.\n\n## Models.\nThe backbone is nnUNetResEncUNetL, without architectural modification. Three models were trained with different patch sizes, focusing on MedialSurfaceRecall: patch 224 (500 epochs), patch 256 (500 epochs), and patch 288 (500 epochs). Different patch sizes provide complementary receptive fields, balancing local surface precision and global continuity.\n\n## Inference & fusion.\nInference followed the standard nnUNet sliding-window pipeline (step_size = 0.9). Patch 224 and 256 used mirroring TTA, while patch 288 did not due to inference speed constraints. The final prediction was obtained by direct mean fusion of the three probability maps, without logit weighting, which showed more stable leaderboard behavior.\n\n## Post-processing (key part).\nMost performance gains came from post-processing. First, gradient anisotropic diffusion was applied twice to the fused probability map (conductance = 2.0, time_step = 0.04) to smooth fragmented responses while preserving sharp surface transitions in probability space.\nSecond, adaptive hysteresis thresholding with directional morphology was applied. Parameters were T_low = 0.50, T_high = 0.90, z_radius = 1, xy_radius = 0, and min_size = 100. Voxels above T_high define high-confidence surface cores, while voxels between T_low and T_high are included only if connected to the core. Morphological connectivity is restricted to the z direction to reflect the thin layered structure of the scroll surface and prevent lateral over-expansion, followed by removal of small isolated components.\n\nA lighter diffusion variant (single iteration, conductance = 1.5, time_step = 0.03) slightly improved private performance (up to 0.618) but reduced the public score (0.595 → 0.593). Compared to using adaptive hysteresis alone, diffusion improved local validation by ~0.005, although its public score was slightly worse. We therefore selected the stronger diffusion setting, trusting the local evaluation and prioritizing overall stability.\n\nOverall, the solution avoids complex architectural tricks and relies on scale diversity, stable mean ensembling, probability-space smoothing, and direction-aware adaptive thresholding.\n\nDue to the Chinese New Year holiday, I was not able to devote much time to the competition during the final two weeks; given that, I am very satisfied with the final ranking. Thanks again to the organizers for this unique and inspiring challenge.\n\nThe inference notebook is [here](https://www.kaggle.com/code/lingyundev/notebook686f6dd4fe).\nCode is [here](https://github.com/LingYunGit/SurfaceDetection_8th_Solution).",
    "3415214": "Interesting. I didn't know about \"gradient anisotropic diffusion\".\n\nIs it different from anisotropic diffusion as in wikipedia https://en.wikipedia.org/wiki/Anisotropic_diffusion ? \n\nYou made me search a bit, and I saw on wikipedia that anisotropic diffusion is a generalization of Gaussian smoothing. I used the latter, I wish I knew about the more general form. \n\nFurther search makes em wonder about which implementation you used. Found some C++ ones, and this python one https://github.com/SimpleITK/SlicerSimpleFilters/blob/master/SimpleFilters/Resources/json/GradientAnisotropicDiffusionImageFilter.json",
    "3415247": "Yes, it is closely related to the anisotropic diffusion described on Wikipedia (Perona–Malik). By “gradient anisotropic diffusion”, I simply mean that the diffusion strength is controlled by the local gradient magnitude, so smoothing is suppressed across strong edges and encouraged in flat regions, unlike Gaussian smoothing.\n\nThe main difference in my usage is that diffusion is applied to the model output probability map, not to the raw image. This helps smooth fragmented responses while preserving thin surface boundaries. The implementation is equivalent in behavior to ITK / SimpleITK’s GradientAnisotropicDiffusionImageFilter.",
    "3415255": "Thanks, learned something from you.",
    "3415524": "there's another python version here https://github.com/ScrollPrize/villa/blob/main/vesuvius/src/vesuvius/image_proc/run/ced.py\n\nthat a number of teams appear to have used , if you're looking for one in python ."
  },
  "source": "meta"
}