Skip to content

Conversation

@StarPlatinum7
Copy link

📝 Description

This pull request introduces support for the MEBIN post-processing method within the Anomalib framework. The implementation includes a new post-processing algorithm that ​​mitigates false positives and false negatives in the binarization results by identifying the threshold interval where connected components remains stable.​ This strategy is proposed in AnomalyNCD (CVPR2025).

✨ Changes

  • Added new post-processing method: src/anomalib/post_processing/mebin_post_processor.py
  • Added new threshold method: src/anomalib/metrics/threshold/mebin.py
  • Updated necessary __init__.py files to expose new modules

Example Usage

Here's how to use the mebin_post_porocessor in your projects:

from anomalib.data import MVTecAD
from anomalib.models import Patchcore
from anomalib.engine import Engine
from anomalib.post_processing import MEBinPostProcessor

# Initialize the datamodule, model and engine
datamodule = MVTecAD(
    category='bottle', # category in mvtec dataset
    root = "./data/mvtec_anomaly_detection", # path where dataset is stored
    train_batch_size = 32,
    eval_batch_size = 32,
)

engine = Engine()

model = Patchcore(
    post_processor=MEBinPostProcessor(
        sample_rate=4,
        min_interval_len=4,
        erode=True
    )
)

# Train the model
engine.train(datamodule=datamodule, model=model)

Select what type of change your PR is:

  • 🚀 New feature (non-breaking change which adds functionality)
  • 🐞 Bug fix (non-breaking change which fixes an issue)
  • 🔄 Refactor (non-breaking change which refactors the code base)
  • ⚡ Performance improvements
  • 🎨 Style changes (code style/formatting)
  • 🧪 Tests (adding/modifying tests)
  • 📚 Documentation update
  • 📦 Build system changes
  • 🚧 CI/CD configuration
  • 🔧 Chore (general maintenance)
  • 🔒 Security update
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)

✅ Checklist

Before you submit your pull request, please make sure you have completed the following steps:

  • 📚 I have made the necessary updates to the documentation (if applicable).
  • 🧪 I have written tests that support my changes and prove that my fix is effective or my feature works (if applicable).
  • 🏷️ My PR title follows conventional commit format.

For more information about code review checklists, see the Code Review Checklist.

@StarPlatinum7 StarPlatinum7 force-pushed the feat/postprocess/add_mebin_post_processor branch from acc97fb to d1d0080 Compare September 3, 2025 10:39
@rajeshgangireddy rajeshgangireddy self-requested a review September 3, 2025 12:39
@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 29.72973% with 78 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/anomalib/metrics/threshold/mebin.py 13.04% 60 Missing ⚠️
...c/anomalib/post_processing/mebin_post_processor.py 51.35% 18 Missing ⚠️

📢 Thoughts on this report? Let us know!

alfieroddan and others added 6 commits September 8, 2025 18:32
…chCore, Padim, Dfkde (open-edge-platform#2913)

* refactor patchcore, use list instead of cat

* typo in patchcore

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>

* padim model to now use cat instead of list

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>

* dfm and padim update cat to list

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>

* add dfkde cat to list changes

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>

* change assert from memory bank to list size, fix pre-commit issues

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>

---------

Signed-off-by: Alfie Roddan <51797647+alfieroddan@users.noreply.github.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
…#2920)

* added histogram of anomaly scores

* Update src/anomalib/metrics/anomaly_score_distribution.py

Co-authored-by: Samet Akcay <samet.akcay@intel.com>
Signed-off-by: Aimira Baitieva <63813435+abc-125@users.noreply.github.com>

* Update anomaly_score_distribution.py

* Update anomaly_score_distribution.py

* Fixed pre-commit checks

---------

Signed-off-by: Aimira Baitieva <63813435+abc-125@users.noreply.github.com>
Co-authored-by: Samet Akcay <samet.akcay@intel.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
* added pg and pb metrics

* fixed typos

* Update __init__.py

* Update __init__.py - removed duplicate

* Update pg_pb.py

* Fixed pre-commit checks

---------

Co-authored-by: Samet Akcay <samet.akcay@intel.com>
Co-authored-by: Rajesh Gangireddy <rajesh.gangireddy@intel.com>
Signed-off-by: StarPlatinum7 <2732981250@qq.com>
@StarPlatinum7 StarPlatinum7 force-pushed the feat/postprocess/add_mebin_post_processor branch from 6717b2b to 575632f Compare September 8, 2025 10:32
Copy link
Contributor

@rajeshgangireddy rajeshgangireddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, Thanks for the addition of this post processor.
Apologies for somehow missing to review it.
I have now left. some comments.

2. Counting connected components at each threshold level
3. Finding stable intervals where component count remains constant
4. Selecting threshold from the longest stable interval

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a link to the AnomalyNCD paper as reference.




def get_threshold(self, anomaly_num_sequence, min_interval_len):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the type annotation for function arguments and returns.

from anomalib.post_processing import MEBinPostProcessor


class TestMEBinPostProcessor:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a circular import error when running this test.
E ImportError: cannot import name 'PostProcessor' from partially initialized module 'anomalib.post_processing' (most likely due to a circular import) (/anomalib/src/anomalib/post_processing/__init__.py)

import sys
sys.path.append(os.getcwd())

from anomalib.post_processing import PostProcessor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid circular import, I think this should work:

Suggested change
from anomalib.post_processing import PostProcessor
from .post_processor import PostProcessor

@rajeshgangireddy
Copy link
Contributor

I have opened a new PR with your commits + my suggestions here : #3030 (that way your contributions are counted).

I will close this PR now, if you don't mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants