# Claude-Video Dedup Threshold of 2.0: How It Handles Slow Fades vs Static Frames

> Understand Claude Video's dedup threshold 2.0. Learn how it distinguishes slow fades from static frames by analyzing pixel differences and luminance changes.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: deep-dive
- Published: 2026-07-08

---

**The dedup threshold of 2.0 in Claude-Video removes near-identical frames when the mean pixel difference is ≤ 2.0 intensity levels, while preserving slow fades because their gradual luminance changes exceed this conservative cutoff when compared to the last kept frame.**

In the bradautomates/claude-video repository, preprocessing raw video into analyzable frames requires intelligent deduplication to avoid redundant analysis of identical content. The `DEDUP_THRESHOLD = 2.0` constant defined in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) serves as the mathematical boundary that determines whether two frames are similar enough to collapse. This aggressive threshold eliminates static slides and rapid cuts while intentionally allowing gradual transitions like slow fades to survive the deduplication phase.

## How the Dedup Threshold of 2.0 Works

### Generating 16×16 Grayscale Thumbnails

The deduplication process begins by generating perceptual fingerprints of each frame. In [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py), the code creates a **16×16 grayscale thumbnail** (controlled by `DEDUP_THUMB = 16`) for every extracted frame. These thumbnails reduce computational overhead while preserving the essential luminance structure needed for comparison.

### Computing Frame Deltas

The `_frame_delta` function calculates the **mean per-pixel absolute difference** between two thumbnails. This produces a single scalar representing the average intensity change across the 256 pixels (16×16). According to the source implementation, if this value is **≤ 2.0**, the later frame is classified as a duplicate and removed from the candidate set.

### The Greedy Deduplication Algorithm

The core logic resides in `_dedupe_by_deltas`, which implements a **greedy comparison strategy**. Rather than comparing each frame against every previous frame, the algorithm only compares the current candidate to the **last kept** frame. This optimization reduces algorithmic complexity while maintaining effectiveness for most video content. When the delta exceeds 2.0, the frame is retained and becomes the new comparison baseline for subsequent frames.

## Why Slow Fades Survive the Conservative Threshold

Slow fades represent gradual luminance transitions spread across many frames. Because the algorithm compares each frame only to the immediately preceding **kept** frame, the **accumulated change** of a long fade quickly exceeds the tiny 2.0 intensity-level threshold.

For example, in a fade spanning multiple seconds, frame *n* might differ from the last kept frame by 1.5 levels, frame *n+1* by 3.0 levels, and so on. Once the delta exceeds 2.0, that frame is retained and becomes the new baseline. This creates a sampling effect where slow fades are represented by a series of frames showing the progression, rather than being collapsed into a single frame. Static slides, by contrast, maintain deltas below 2.0 and are aggressively deduplicated.

## Implementing Custom Thresholds in Your Pipeline

While the default `dedupe_perceptual` function uses the 2.0 threshold, you can adjust this value for stricter or looser deduplication. Lower values preserve more frames (e.g., 1.0), while higher values collapse more frames (e.g., 5.0).

```python
from pathlib import Path
from skills.watch.scripts import frames

# Extract frames without deduplication

candidates = frames.extract(
    video_path="video.mp4",
    out_dir=Path("frames"),
    fps=1.0,
)

# Apply perceptual deduplication with default threshold (2.0)

deduped, dropped = frames.dedupe_perceptual(candidates)
print(f"Deduped {dropped} frames out of {len(candidates)}")

# Use a stricter threshold to keep more frames

deduped_strict, _ = frames.dedupe_perceptual(candidates, threshold=1.0)

# Use a looser threshold to collapse more frames

deduped_loose, _ = frames.dedupe_perceptual(candidates, threshold=5.0)

```

When processing a video containing slow fades, the default `deduped` list will contain nearly all original candidates because each frame's thumbnail delta exceeds 2.0. When processing static slides or rapid cuts where content doesn't change, the `dropped` count will be significantly higher.

## Summary

- **`DEDUP_THRESHOLD = 2.0`** is defined in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) as a conservative cutoff for frame deduplication.
- The algorithm uses **16×16 grayscale thumbnails** and calculates the mean per-pixel absolute difference (`_frame_delta`) to compare frames.
- Only frames with average pixel changes of **≤ 2.0 intensity levels** are collapsed; the threshold is inclusive.
- A **greedy comparison** to the last kept frame ensures that slow fades survive while static content is removed.
- The `dedupe_perceptual` function accepts a custom `threshold` parameter for adjusting deduplication aggressiveness.
- Unit tests in [`tests/test_dedup.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_dedup.py) (specifically `test_dedupe_threshold_is_inclusive`) verify that deltas exactly equal to 2.0 are treated as duplicates.

## Frequently Asked Questions

### What happens if I set the dedup threshold lower than 2.0?

Setting the threshold below 2.0 (e.g., 1.0) makes the deduplication more aggressive at preserving frames. Because fewer frames will have mean pixel differences below this stricter cutoff, more frames are retained from the video stream. This is useful when analyzing content with subtle animations or slight camera movements that you want to preserve.

### Does the dedup threshold of 2.0 affect fast cuts or only static slides?

The dedup threshold of 2.0 affects both, but behaves differently for each. **Static slides** maintain differences below 2.0 and are collapsed into single representative frames. **Fast cuts** that change scene content typically exceed the 2.0 threshold immediately, so both the pre-cut and post-cut frames are preserved. Only rapid cuts that result in visually identical frames (rare in natural video) would be collapsed.

### How does Claude-Video calculate the frame delta for deduplication?

Claude-Video calculates the frame delta using the `_frame_delta` function in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py). This function computes the mean absolute difference between two 16×16 grayscale thumbnails. Each thumbnail is generated by resizing the full frame and converting to grayscale, creating a lightweight perceptual hash that compares luminance rather than color or high-frequency detail.

### Is the dedup threshold inclusive or exclusive?

The dedup threshold is **inclusive**. As verified by the `test_dedupe_threshold_is_inclusive` test in [`tests/test_dedup.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_dedup.py), a delta exactly equal to 2.0 is still regarded as a duplicate and the frame is removed. The comparison uses `<= threshold` logic, meaning any mean pixel difference of 2.0 or less triggers deduplication.