ncd — IMGMETRICS compression op

• 数据种类:image2d × image2d → scalar

• 调用: import fullseye as fs; fs.ledger.ncd(a, b, compressor='lzma', levels=None, data_range=None, symmetric=True)(要直接调用实现,import imgmetrics; imgmetrics.ncd(a, b, compressor='lzma', levels=None, data_range=None, symmetric=True);从台账取用则 opsimgmetrics.get("ncd"))

用法

归一化压缩距离(Li, Chen, Li, Ma & Vitányi, IEEE TIT 50(12), 2004)。

NCD(x,y) = (C(xy) - min(C(x),C(y))) / max(C(x),C(y))。相同的输入趋近 0,无关的趋近 1 —— 但实际的压缩器不是理想的 Kolmogorov 复杂度,所以即使输入相同也不会严格为 0 (有头部带来的偏置)。该偏置的实测值记录在测试中。

不接受原始的 float 数组。压缩器看的是字节序列的重复,所以值只要有极细微的差别,float 的尾数部分就会全部换掉,即使是相似的 2 幅图共同的字节序列也会消失。实测(2026-09-02,linspace 的渐变与它 +0.02 后的图,PSNR 34.0 dB = 非常相似):

• 保持 float64:8 字节字的共享率 0.02 % → NCD 1.0959 (读起来是“完全无关”的值,而且超过 1)

• 量化为 256 级:NCD 0.1290(正确地“非常相似”)

• 真正无关的 2 幅图:NCD 0.9981

也就是说,以 float 原样测量会无一例外地得出相反的结论。因此对 float 要求显式给出 levels(levels=256 时把 data_range 量化为 256 级后再测)。整数 dtype 可以原样测量。

symmetric=True(默认)测量两个方向并取平均。压缩器从前往后依次建立字典,所以 C(xy) != C(yx),朴素实现会一边自称“距离” 一边随参数顺序改变数值(实测:竖条纹与横条纹 0.571429 对 0.595238, 相对 4 %)。均匀随机数之间差为 0.000e+00,所以只要用随机数测试就无法察觉 —— 这是在有结构的真实数据上才会暴露的那类缺陷。

详细使用指南

• image_difference_metrics 族使用指南

参考(示例数据、文献)

• 示例数据目录(下载 URL / 许可证) —— 2-D 用 skimage.data(BSD/公有领域)加合成图,3-D 给出真实数据源(Stanford/PDS 等)的下载 URL。

• 算子来历与参考文献 —— 该算子族所依据的研究/方法出处。

• 算法的正典(作者、年份)与用途见上面的族使用指南。

可运行的示例(实际调用该算子并已验证的样例)

• image_quality_metrics — py -3.11 examples/image_quality_metrics.py

类型可衔接的下一个算子(可接受 scalar 作为输入)

luma_limited_u8 · rank_data · tid2013_index

同类别(compression)

compressed_size


*Provenance: imgmetrics.py — IMGMETRICS 算子登记表。本条目由 tools/opdocs.py md 自动生成(请勿手工编辑)。*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.