-
Notifications
You must be signed in to change notification settings - Fork 603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Use Perlin ROI to create noise on to the object of interest #1061
base: main
Are you sure you want to change the base?
Conversation
…nomalib into feature/augment_roi
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great addition! Thanks. The only thing I am concerned about is the keys in config. It might require some design. But it is something we will have to discuss internally.
@@ -13,9 +13,11 @@ dataset: | |||
transform_config: | |||
train: null | |||
eval: null | |||
test_split_mode: from_dir # options: [from_dir, synthetic] | |||
test_split_mode: synthetic # options: [from_dir, synthetic] | |||
test_synthetic_type: perlin_roi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe these should live under a separate key. Since synthetic
is optional test_synthetic_mode
probably shouldn't be at the same level as other keys.
How about?
test_split:
mode: synthetic/from_dir
optional_key1: ...
optional_key2: ...
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Ashwin, thanks for the suggestion. We will work on the changes and keep you updated.
Indeed, the flexibility to choose various generation methods (test set & validation set) might require further processing during setup, perhaps in a separate discussion/PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @ashwinvaidya17 can we proceed with this design? We would like your approval before we make any changes as many codes will be impacted.
test_split:
mode: synthetic # options: [from_dir, synthetic]
type: perlin_roi
ratio: 0.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since @djdameln designed this, he might have better insight regarding the design. We can wait for his feedback.
return synthetic_dataset | ||
|
||
return make | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def synthetic_dataset_from_samples(): | ||
def make_perlinroi_synthetic_dataset(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since both the methods are very similar, we can use mark.parameterize
https://docs.pytest.org/en/6.2.x/parametrize.html#pytest-mark-parametrize-parametrizing-test-functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, we will work on the changes. Thanks again Ashwin
src/anomalib/data/utils/augmenter.py
Outdated
) | ||
perturbation, mask = self.generate_perturbation(height, width, anomaly_source_path) | ||
perturbations_list.append(Tensor(perturbation).permute((2, 0, 1))) | ||
masks_list.append((Tensor(mask).permute((2, 0, 1)) * thresh_batch)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except for thresh_batch
here this is similar to the base method. Maybe we can just add an if statement in the base class and add this line there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea, added this and removed the child method
|
||
def gaussian_blur(self, image: Tensor, transform: A.Compose) -> tuple[Tensor, Tensor]: | ||
"""Generate Gaussian Blur. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also describe the intention behind performing gaussian blur and finding out the thresholds based on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we renamed the function generate_roi
as it does more than gaussian blur. The intention is to generate the region of interest.
|
||
cv2.bitwise_not(thresh) | ||
|
||
if thresh[0, 0] & thresh[-1, -1] & thresh[-1, 0] & thresh[0, -1] == 255: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this line? From what I understand this inverts the image if the background is white
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to your understanding: if all four corners of the image are white, we invert the mask.
we added this as a comment in the code base as well
src/anomalib/data/utils/augmenter.py
Outdated
|
||
|
||
class PerlinROIAugmenter(Augmenter): | ||
def augment_batch(self, batch: Tensor, thresh_batch: Tensor | None = None) -> tuple[Tensor, Tensor]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a short description on how this works. Something like, extracts foreground object based on binary thresholding and limits perlin noise augmentation to that region.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added as the docstring for this class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This could be a useful addition to our Perlin noise mechanism. Overall I have the same comments as Ashwin, in that some more explanation about the methods used to obtain the final noise masks could be provided in the docstrings.
src/anomalib/data/folder_3d.py
Outdated
@@ -292,8 +294,10 @@ class Folder3D(AnomalibDataModule): | |||
during validation. | |||
Defaults to None. | |||
test_split_mode (TestSplitMode): Setting that determines how the testing subset is obtained. | |||
test_synthetic_type (TestSyntheticType): Method for generating synthetic test data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if it makes sense to expose these parameters to the 3d datasets. The anomalous augmentations are only applied to the images, not to the 3d point cloud data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @djdameln, we removed it from this dataset. please let us know if there are more.
src/anomalib/data/utils/augmenter.py
Outdated
"""Generate anomalous augmentations for a batch of input images. | ||
|
||
Args: | ||
batch (Tensor): Batch of input images | ||
thresh_batch (Tensor | None, optional): Batch of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this parameter description is incomplete
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comment and refactored the class based on @ashwinvaidya17's suggestions
Description
Provide a summary of the modification as well as the issue that has been resolved. List any dependencies that this modification necessitates.
Our aim is to generate fake anomalous images for the validation set, and then use Anomalib's existing adaptive thresholding mechanism. But the current Perlin Noise augmentation will cover the whole image instead of the object of interest.
To automatically segment out the ROI Mask of the object given an image and then implement Perlin Noise onto the object only.
Code changes:
Augmenter
to create another class callPerlinROIAugmenter
PerlinROIAugmenter
Dataset
to access synthetic type (default: Perlin) fromconfig.yaml
Changes
Checklist