---
title: "How to add rack focus with Claude (tested prompt and script)"
description: "The serum bottle starts crisp against a soft, dreamy backdrop, then at 1.5 seconds the focus slides back so the bottle melts into blur while the acrylic block and the holographic folds behind it turn sharp. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/rack-focus
---

# How to add rack focus with Claude

The serum bottle starts crisp against a soft, dreamy backdrop, then at 1.5 seconds the focus slides back so the bottle melts into blur while the acrylic block and the holographic folds behind it turn sharp.

Made by the script on this page, from our own test clip.

## Get this effect

1. ### Switch to Code in your [Claude Desktop App](https://claude.com/download)

2. ### Install the skill (once)

   ```
   Install the Recharm video effects skill: download https://recharm-growth-staging.s3.us-east-2.amazonaws.com/website/downloads/recharm-video-effects.zip and unzip it into ~/.claude/skills
   ```

3. ### Ask for the effect

   ```
   Add rack focus to input.mp4
   Out-of-focus blur (Gaussian sigma) as a share of the frame width: 13.5 pixels on a 540-wide video: 0.025
   Second the focus pull starts: 1.5
   ```

## Several videos, several effects, one ask

Put your clips in the folder, mention them with @, and ask for everything at once. Claude runs one tested script after another on each clip, then joins them.

Add rack focus to **@clip1.mp4**, put a sale badge on **@clip2.mp4**, give **@clip3.mp4** a VHS look, then join all three with crossfades.

## Settings you can change

Ask Claude to change any of these, or edit them at the top of the script.

| Setting      | Default | What it does                                                                                                |
| ------------ | ------- | ----------------------------------------------------------------------------------------------------------- |
| `BLUR`       | `0.025` | Out-of-focus blur (Gaussian sigma) as a share of the frame width: 13.5 pixels on a 540-wide video.          |
| `START`      | `1.5`   | Second the focus pull starts.                                                                               |
| `PULL`       | `1.0`   | Seconds the focus takes to move from the product to the backdrop.                                           |
| `MASK_EVERY` | `3`     | Cut the product out on every Nth frame and reuse the mask in between. 1 is most accurate, higher is faster. |

## Without the skill

Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.

```
Add a rack focus to input.mp4 (540x960, 30fps, 6 seconds) with Python: use rembg (session "u2net") to cut the bottle out of the frames as a soft mask, OpenCV (cv2.GaussianBlur) for the blur and ffmpeg to read and write the video. Treat the bottle and everything else (the backdrop and the acrylic block) as two layers. Until 1.5 seconds the bottle is fully sharp and the backdrop is blurred with a Gaussian sigma of 13.5 pixels (2.5% of the frame width). From 1.5 to 2.5 seconds, with a smoothstep ease, the backdrop's blur goes from 13.5 to 0 while the bottle's goes from 0 to 13.5; after 2.5 seconds the backdrop stays fully sharp and the bottle fully blurred to the end. Blur the bottle as its own layer (blur the frame times the mask and the mask itself by the same sigma, then put it over the backdrop with the blurred mask as alpha) so its soft edge spreads over the sharp backdrop, and before blurring the backdrop fill the bottle's hole with the surrounding backdrop colors so no purple smears into it. Don't zoom, darken or move the frame. There's no text to draw, but if you add any, draw it with Pillow, not ffmpeg's drawtext. Keep the size, frame rate and audio, encode H.264 yuv420p and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `rack-focus.py` and run:

```
python3 rack-focus.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Rack focus: the shot opens sharp on the product with a soft backdrop, then focus pulls back so the product goes soft and the backdrop comes sharp.

Usage: python3 rack-focus.py input.mp4 output.mp4
Needs ffmpeg, OpenCV, numpy, Pillow and rembg to cut the product out of every frame
(pip install opencv-python-headless numpy pillow "rembg[cpu]"; rembg downloads its u2net model on first use).
"""
import json
import subprocess
import sys

import cv2
import numpy as np
from PIL import Image
from rembg import new_session

BLUR = 0.025     # out-of-focus blur (Gaussian sigma) as a share of the frame width: 13.5 px on a 540-wide video
START = 1.5      # second the focus pull starts
PULL = 1.0       # seconds it takes to move from the product to the backdrop
MASK_EVERY = 3   # cut the product out on every Nth frame and reuse it in between (the camera moves slowly)

def blur(img, sigma):
    return cv2.GaussianBlur(img, (0, 0), sigma, borderType=cv2.BORDER_REFLECT) if sigma > 0.3 else img

def paint_out(img, keep):
    """Fill the product's hole with the backdrop colors around it (worked out at quarter size, as it's smooth)."""
    small = (w // 4, h // 4)
    color = blur(cv2.resize(img * keep, small, interpolation=cv2.INTER_AREA), w * 0.0125)
    weight = blur(cv2.resize(keep, small, interpolation=cv2.INTER_AREA), w * 0.0125)
    return cv2.resize(color / np.maximum(weight, 1e-3)[:, :, None], (w, h), interpolation=cv2.INTER_LINEAR)

def focus(t):
    """0 while the product is in focus, easing to 1 once the backdrop is."""
    p = min(max((t - START) / PULL, 0), 1)
    return p * p * (3 - 2 * p)

def rack(rgb, mask, t):
    """Defocus the product and the backdrop as two layers, each by its own amount, and stack them."""
    img = rgb.astype(np.float32)
    # the backdrop with the product painted out, so blurring it doesn't smear the product's colors around
    keep = 1 - cv2.dilate(mask, np.ones((9, 9), np.uint8))[:, :, None]
    plate = img * keep + paint_out(img, keep) * (1 - keep)
    backdrop = blur(plate, BLUR * w * (1 - focus(t)))
    # the product as a layer with its own soft edge, spreading over the backdrop as it goes out of focus
    sigma = BLUR * w * focus(t)
    product, alpha = blur(img * mask[:, :, None], sigma), blur(mask, sigma)[:, :, None]
    return (product + backdrop * (1 - alpha)).clip(0, 255).round().astype(np.uint8)

def probe(path):
    info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
                                               "stream=width,height,r_frame_rate", "-of", "json", path]))
    s = info["streams"][0]
    num, den = s["r_frame_rate"].split("/")
    return s["width"], s["height"], s["r_frame_rate"], float(num) / float(den)

def render(src, out):
    """Read src frame by frame, rack the focus and save to out, keeping the audio."""
    reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
                              stdout=subprocess.PIPE)
    writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error",
                               "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}", "-r", rate, "-i", "-",
                               "-i", src, "-map", "0:v", "-map", "1:a?", "-c:v", "libx264", "-crf", "18",
                               "-pix_fmt", "yuv420p", "-c:a", "copy", "-shortest", out], stdin=subprocess.PIPE)
    i = 0
    while raw := reader.stdout.read(w * h * 3):
        rgb = np.frombuffer(raw, np.uint8).reshape(h, w, 3)
        if i % MASK_EVERY == 0:
            mask = np.asarray(session.predict(Image.fromarray(rgb))[0], np.float32) / 255
        writer.stdin.write(rack(rgb, mask, i / fps).tobytes())
        i += 1
    writer.stdin.close()
    if reader.wait() or writer.wait():
        sys.exit("ffmpeg failed")

src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
session = new_session("u2net")
render(src, out)
```

## More motion and camera

- [2.5D parallax photo **2.5D parallax photo**](https://www.recharm.com/effects/2-5d-parallax-photo)
- [Back-and-forth loop **Back-and-forth loop**](https://www.recharm.com/effects/back-and-forth-loop)
- [Background blur **Background blur**](https://www.recharm.com/effects/background-blur)
- [Bullet time **Bullet time**](https://www.recharm.com/effects/bullet-time)
- [Cinemagraph **Cinemagraph**](https://www.recharm.com/effects/cinemagraph)

## Find 3x _winning ads_

Recharm cuts your ad footage into tagged, searchable clips: hooks, testimonials, product shots. Find the shots that win, add the effect with Claude, and ship 3x more ad edits.

[Start 14-day free trial](https://www.recharm.com/get-started)
