Uniform LBP算子Python实现代码

Uniform LBP(均匀LBP)

为解决二进制模式过多的问题,提高统计性,Ojala提出了采用一种“等价模式”(Uniform Pattern)来对LBP算子的模式种类进行降维。Ojala等认为,在实际图像中,绝大多数LBP模式最多只包含两次从1到0或从0到1的跳变。因此,Ojala将“等价模式”定义为:当某个LBP所对应的循环二进制数从0到1或从1到0最多有两次跳变时,该LBP所对应的二进制就称为一个等价模式类。如00000000(0次跳变),00000111(只含一次从0到1的跳变),10001111(先由1跳到0,再由0跳到1,共两次跳变)都是等价模式类。除等价模式类以外的模式都归为另一类,称为混合模式类,例如10010111(共四次跳变)。通过这样的改进,二进制模式的种类大大减少,而不会丢失任何信息。模式数量由原来的2P种减少为 P ( P-1)+2种,其中P表示邻域集内的采样点数。对于3×3邻域内8个采样点来说,二进制模式由原始的256种减少为58种,即:它把值分为59类,58个uniform pattern为一类,依次从大到小排序;其它的所有值为第59类。这样直方图从原来的256维变成59维。这使得特征向量的维数更少,并且可以减少高频噪声带来的影响。
Python代码:

import numpy as np
import cv2
import os
np.set_printoptions(threshold = 1e6)
def arry_58():
    l = np.zeros(58, dtype=int)
    m = []
    a = -1
    for i in range(256):
        bit = '{:08b}'.format(i)  # 二进制化
        arry = []  # 二进制生成数组
        count = 0  # 计数变化次数
        # 把字符串变为数组方便统计变化次数
        for x in range(len(bit)):
            arry.append(int(bit[x]))
        # print(arry)
        first = arry[0]  # 数组第一个为first,与之后的比较
        for j in range(1, len(arry)):
            if arry[j] != first:  # 如果变化,计数单位加1
                count += 1
                first = arry[j]  # 并且把变化的值重新赋值
        # print(count)
        if count <= 2:  # 如果变化次数小于2,则依次排序
            a += 1
            # print(i)
            l[a] = i
    l = l.tolist()
    return l
def uniform_LBP(img):
    h, w = img.shape  # 图像的长和宽
    dst = np.zeros((h - 2, w - 2), dtype=img.dtype)  # 新建一张图
    # dst = np.zeros(img.shape, dtype=img.dtype)  # 新建一张图
    arry58 = arry_58()
    for i in range(1, h - 1):
        for j in range(1, w - 1):
            center = img[i][j]
            code = []
            count = 0

            code7 = img[i - 1][j - 1]
            if code7 >= center:
                code7 = 1
            else:
                code7 = 0
            code.append(code7)

            code6 = img[i - 1][j]
            if code6 >= center:
                code6 = 1
            else:
                code6 = 0
            code.append(code6)

            code5 = img[i - 1][j + 1]
            if code5 >= center:
                code5 = 1
            else:
                code5 = 0
            code.append(code5)

            code4 = img[i][j + 1]
            if code4 >= center:
                code4 = 1
            else:
                code4 = 0
            code.append(code4)

            code3 = img[i + 1][j + 1]
            if code3 >= center:
                code3 = 1
            else:
                code3 = 0
            code.append(code3)

            code2 = img[i + 1][j]
            if code2 >= center:
                code2 = 1
            else:
                code2 = 0
            code.append(code2)

            code1 = img[i + 1][j - 1]
            if code1 >= center:
                code1 = 1
            else:
                code1 = 0
            code.append(code1)

            code0 = img[i][j - 1]
            if code0 >= center:
                code0 = 1
            else:
                code0 = 0
            code.append(code0)
            LBP = code7*128 + code6*64 + code5*32 + code4*16 + code3*8 + code2*4 + code1*2 + code0*1
            #print("LBP值为:",LBP)
            #print("8位编码为:",code)
            first = code[0]  # 数组第一个为first,与之后的比较
            for x in range(1, len(code)):
                if code[x] != first:  # 如果变化,计数单位加1
                    count += 1
                    first = code[x]  # 并且把变化的值重新赋值
            #print("跳变次数",count)
            if count > 2:  # 如果变化次数大于3,则归为59位
               dst[i - 1][j - 1] = 58
            else:  # 否则,按原来的数计算
                loca = arry58.index(LBP)  # 获取位置
                dst[i - 1][j - 1] = loca
    return dst

if __name__ == '__main__':
    gray = cv2.imread('./b.jpg', cv2.IMREAD_GRAYSCALE)
    print(gray.shape)
    a = uniform_LBP(gray)
    cv2.imshow('uniform_lbp', a)
    cv2.imwrite("./2.jpg", a)
    cv2.waitKey(0)

Uniform LBP算子Python实现代码_第1张图片Uniform LBP算子Python实现代码_第2张图片

你可能感兴趣的:(LBP)