关于scikit-image库local_binary_pattern()函数返回图像机制及uniform模式旋转不变性的疑问
关于scikit-image库local_binary_pattern()函数返回图像机制及uniform模式旋转不变性的疑问
嘿,我来帮你把这个问题掰扯明白——刚好之前做特征提取的时候,对着LBP的源码和文档啃了好久!
首先说为什么函数返回的是图像而不是直方图:你的那个朋友说的完全没错!local_binary_pattern()默认的逻辑(除非你专门去统计全局直方图),就是给每个中心像素单独计算LBP编码值。
就拿你说的radius=1, n_points=4的场景来说:
- 每个3x3窗口的中心像素,会和上下左右四个邻域像素逐一对比,生成一个4位的二进制串(比如邻域像素≥中心就记1,否则记0)
- 把这个二进制串转成十进制整数(比如0010就是2),这个整数就是该中心像素的LBP编码
- 把所有像素的LBP编码按原图像的位置排列,就得到了输出的“LBP图像”——每个像素值对应原图像对应位置的LBP编码,确实是16个灰度级。
接下来是你最关心的uniform模式的旋转不变性问题,你提到的“邻域顺序影响编码”这个点切中了普通LBP的痛点,但uniform模式的处理逻辑完全不同:
首先明确什么是uniform LBP模式:它指的是二进制编码(首尾相连后)中,0和1之间的跳变次数不超过2的模式。比如0000(无跳变)、0001(1次跳变)、0011(1次跳变)这些都算,而像0101这种跳变3次的就不属于uniform。scikit-image里的uniform模式会把所有符合条件的uniform模式分别映射到不同的整数,所有非uniform模式统一映射到一个单独的整数。
而它实现旋转不变性的核心是:对每个LBP模式,取它所有旋转等价版本中的最小整数作为最终编码。举个例子:
- 假设按上、左、下、右的顺序得到编码0010(十进制2),把这个二进制串旋转90度(对应邻域顺时针转90度,顺序变成左、下、右、上),得到0100(4),再转90度是1000(8),再转是0001(1)
- 在uniform模式下,这个模式的所有旋转版本里最小的整数是1,所以不管你原始邻域是哪个旋转角度,最终编码都会被统一成1
- 这样一来,不管图像中的特征怎么旋转,对应的LBP编码都是同一个值,自然就实现了旋转不变性。
简单说,scikit-image的uniform模式不是直接按固定邻域顺序生成编码,而是先对所有旋转等价的LBP模式做了“归一化”,映射到同一个代表值,这就解决了顺序/旋转带来的编码差异问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

