AVIF 可変品質(Adaptive Q)戦略:複雑度/領域別にビットを再配分する
AVIFの単一Q指定は 低周波領域に過剰ビット / 高周波領域で不足 という偏りを生みます。Adaptive Q は領域複雑度と主観保持を両立する再配分アプローチです。
TL;DR
- 1パス統計 → 重要度スコア融合 → Qマップ → 2パス再エンコード
- 勾配・局所分散・SSIM残差を複合
- CIで逸脱検知しモデル調整を継続
1. なぜ Adaptive Q が必要か
単一品質は フラット背景 に余剰を割り当て、ヘアライン/テクスチャ で破綻します。領域ごとの 劣化しやすさ を数値化し、差分を平準化するのが目的です。
2. 全体フロー
- 低Q(高速)で1パス統計エンコード
- 勾配・分散・SSIM 近似を収集
- スコア融合 & 正規化
- Qマップ生成(オフセット ±span)
- 2パス本番エンコード
- PSNR/SSIM/VMAF を CI で回帰検知
3. 実装スニペット
3.1 統計収集
// 1st pass: collect block stats (pseudo)
for (const block of frame.blocks) {
const grad = sobel(block.pixels); // 勾配強度
const varc = variance(block.pixels); // 局所分散
const ssimPred = predictSSIM(block.pixels); // 近似モデル
stats.push({ id: block.id, grad, varc, ssimPred });
}
3.2 スコア融合
// Score fusion → normalized importance (0..1)
const maxG = max(stats.map(s=>s.grad));
const maxV = max(stats.map(s=>s.varc));
for (const s of stats){
const g = s.grad / (maxG||1);
const v = s.varc / (maxV||1);
const p = 1 - s.ssimPred; // 劣化しやすさ
s.score = 0.5*g + 0.3*v + 0.2*p; // weight tuning
}
normalize(stats,'score'); // => importance
3.3 Qマップ生成
// Derive Q offset map (lower Q = higher quality)
for (const s of stats){
const baseQ = 40; // global target
const span = 12; // +- range
const importance = s.score; // 0..1
const q = baseQ + span*(0.5 - importance); // high importance -> lower Q
qMap[s.id] = clamp(Math.round(q), 18, 60);
}
3.4 2パスエンコード
// 2nd pass: encode with per-block Q
for (const block of frame.blocks){
const q = qMap[block.id];
encodeBlock(block, { q });
}
4. Qマップ設計指針
スコアの分布が偏る場合は log(1+x)
などで圧縮し、極端な低Q/高Q集中を避けます。Adaptive Q は過剰に振れると 知覚的フリッカ を生むため、空間的平滑化(3x3平均)も併用。
指標 | 目的 | 注意 |
---|---|---|
勾配(sobel) | エッジ/細線保持 | ノイズも拾う→平滑化 |
局所分散 | テクスチャ密度 | 高周波ノイズと混同 |
SSIM予測 | 知覚劣化の粗推定 | 計算コスト |
5. CI での回帰検知
Quality Ladder を ツール で生成し JSON を比較することで、Adaptive Q ロジック更新による劣化をブロックできます。
# CI: Detect regression (pseudo)
BASE=main
NEW=HEAD
node scripts/ladder.js --image sample.png --out before.json --ref $BASE
node scripts/ladder.js --image sample.png --out after.json --ref $NEW
node scripts/metrics-compare.js before.json after.json --psnr-delta-threshold 0.25 --ssim-delta-threshold 0.004 || exit 1
6. FAQ
- Qマップの平滑化フィルタは? → 3x3 box か bilateral の軽量版
- VMAF 使わない理由? → モバイル端末CIコストを抑えるため first cut は SSIM/PSNR
7. まとめ
Adaptive Q は “足りない所へだけビットを再配分” する戦術です。単一Qから始め問題領域を統計化→再配分→CI 監視で継続改善してください。