Skip to content
Back to skills

Frame Differencing Temporal Encoding

ASecurity

Encode motion and velocity by computing per-channel pixel differences between consecutive frames instead of stacking raw frames for RL visual observations

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

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill frame-differencing-temporal-encoding --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frame Differencing Temporal Encoding?

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

Security grade badge for Frame Differencing Temporal Encoding
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-frame-differencing-temporal-encoding/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-frame-differencing-temporal-encoding)

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-frame-differencing-temporal-encoding
description: Encode motion and velocity by computing per-channel pixel differences between consecutive frames instead of stacking raw frames for RL visual observations
---

# Frame Differencing Temporal Encoding

## Overview

Frame stacking (concatenating the last N frames) is the standard way to give RL agents temporal information from visual observations. Frame differencing is a lighter alternative: subtract the previous frame from the current one to produce a motion-only image. Moving objects appear as non-zero pixels while static backgrounds cancel out, giving the network explicit velocity signals without doubling the input channels.

## Quick Start

```python
import numpy as np
from collections import deque

class FrameDiffWrapper:
    def __init__(self, env, n_channels=4):
        self.env = env
        self.n_channels = n_channels
        self.buffer = deque(maxlen=2)

    def reset(self):
        obs = self.env.reset()
        frame = obs / 255.0
        self.buffer.append(frame)
        self.buffer.append(np.zeros_like(frame))
        return self._diff()

    def step(self, action):
        obs, reward, done, info = self.env.step(action)
        self.buffer.append(obs / 255.0)
        return self._diff(), reward, done, info

    def _diff(self):
        diff = np.empty_like(self.buffer[1])
        for c in range(diff.shape[-1]):
            diff[..., c] = self.buffer[1][..., c] - self.buffer[0][..., c]
        return diff
```

## Workflow

1. Maintain a deque of the last 2 frames (normalized to [0, 1])
2. At each step, compute per-channel difference: `current - previous`
3. Feed the difference image to the policy network instead of stacked frames
4. Moving objects have large positive/negative values; static regions are ~0
5. Optionally combine: stack one raw frame + one diff frame for position + velocity

## Key Decisions

- **Diff vs. stack**: diff uses half the channels (1 vs. 4) with comparable performance for motion-centric tasks
- **Normalization**: normalize to [0, 1] before differencing to keep values in [-1, 1]
- **Combined mode**: raw frame + diff frame gives both position and velocity — best of both worlds
- **Multiple diffs**: stack 2-3 consecutive diffs for acceleration information (diminishing returns)
- **Sparse motion**: in games with few moving objects, diff frames are mostly zero — use sparse convolutions or skip connections

## References

- [Convolutional Deep-Q learner](https://www.kaggle.com/code/garethjns/convolutional-deep-q-learner)

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…