Skip to content
Back to skills

Microscope Circular Mask Aug

ASecurity

Mask the corners of a dermoscopy image with a random-radius black circle to mimic the dark vignette of a dermatoscope field of view

  • 61 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
datapython

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill microscope-circular-mask-aug --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Microscope Circular Mask Aug?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Microscope Circular Mask Aug
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-microscope-circular-mask-aug/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-microscope-circular-mask-aug)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-microscope-circular-mask-aug
description: Mask the corners of a dermoscopy image with a random-radius black circle to mimic the dark vignette of a dermatoscope field of view
---

## Overview

About half the dermoscopy images in ISIC datasets have the characteristic dark circular vignette of a dermatoscope; the other half are cropped rectangles. Models pick up the vignette as a shortcut feature correlated with source site, which breaks cross-site generalization. The fix is a symmetric augmentation: apply a random-radius circular mask to train images that don't have one, so the model learns to ignore the vignette. Cheap, interpretable, and directly closes a train/test distribution gap.

## Quick Start

```python
import cv2
import numpy as np
import random

class MicroscopeMask:
    def __init__(self, p=0.5):
        self.p = p

    def __call__(self, img):
        if random.random() > self.p:
            return img
        h, w = img.shape[:2]
        circle = (np.ones(img.shape) * 255).astype(np.uint8)
        radius = random.randint(h // 2 - 3, h // 2 + 15)
        circle = cv2.circle(circle, (w // 2, h // 2), radius, (0, 0, 0), -1)
        mask = circle - 255                      # 0 inside circle, -255 outside
        return np.multiply(img, mask)            # zeros outside the circle
```

## Workflow

1. Place the aug in the train transform pipeline before normalization
2. Randomize the radius within a narrow band around `img_size / 2` — keeps the lesion visible while varying the vignette
3. Apply with `p=0.5` since roughly half the images already have a vignette
4. Validate by plotting a grid of augmented samples before kicking off training
5. Track val AUC across sites — this aug specifically lifts underrepresented sites

## Key Decisions

- **Hard black mask, not soft**: dermatoscope vignettes are hard-edged; matching that edge is important for the model to learn the boundary.
- **Random radius**: a fixed radius teaches the model to rely on that exact edge; randomizing forces invariance.
- **Apply before normalization**: normalization expects full-range pixel values; the black mask would shift distribution means if applied after.
- **vs. removing vignettes**: cropping to an inscribed square loses lesion context and shrinks effective resolution.

## References

- [Melanoma. Pytorch starter. EfficientNet](https://www.kaggle.com/code/nroman/melanoma-pytorch-starter-efficientnet)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…