Notas de estudio de LBP (2) --- características del modo invariable de rotación (implementación de código)

        Se recomienda leer el siguiente contenido después de leer las notas del estudio LBP (1) para que sea más fácil comenzar

1. Una breve descripción del modelo invariante de rotación LBP

El patrón binario local invariable en rotación se refiere a la representación de características con invariancia en rotación al realizar un procesamiento invariable en rotación en la característica LBP sobre la base de la característica de patrón binario local (LBP). Debido a que la función LBP tiene las ventajas de la invariancia de escala de grises y la invariancia de rotación, se ha utilizado ampliamente en los campos del procesamiento de imágenes y la visión artificial.

Las características LBP de rotación invariable se pueden calcular mediante el método de modo equivalente y el método de ponderación de rotación invariable. El número de modos equivalentes de características LBP se puede obtener mediante el método de modos equivalentes, eliminando así la influencia de la rotación de la imagen en la extracción de características. Con el método de peso de rotación invariable, se pueden asignar diferentes pesos a los píxeles alrededor del punto de referencia para suprimir algunos efectos de rotación invariable.

Cuando no se usa el modo de rotación invariable, el cálculo de la característica LBP es simple, pero se verá afectado por factores como la rotación de la imagen y los cambios en la escala de grises, lo que resultará en una extracción de características imprecisa. El uso del modo invariable de rotación puede evitar la interferencia de estos factores y mejorar la solidez de las características de LBP en escenarios de aplicación práctica.

2. Implementación de código (funciones clave y código completo)

1. Travesía de píxeles para obtener características de patrones invariantes de rotación

# 获取图像的LBP旋转不变模式特征
def lbp_revolve(self, image_array):
    revolve_array = np.zeros(image_array.shape, np.uint8)
    width = image_array.shape[0]
    height = image_array.shape[1]
    for i in range(1, width - 1):
        for j in range(1, height - 1):
            sum = self.calute_basic_lbp(image_array, i, j)[0]
            revolve_key = self.get_min_for_revolve(sum)
            revolve_array[i, j] = self.revolve_map[revolve_key]
    return revolve_array

sum es la secuencia binaria obtenida después de que el algoritmo de características originales LBP procese la imagen en escala de grises de la imagen original

revolve_key es el número decimal más pequeño obtenido por la suma después de una rotación continua

Luego use revolve_key como la clave del diccionario revolve_map y asigne su valor correspondiente (es decir, valor de píxel) a revolve_array[i,j]

2. Obtenga la secuencia binaria del valor de comparación de los ocho campos

# 图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较
# 比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列
def calute_basic_lbp(self, image_array, i, j):
    sum = []
    num = 0
    if image_array[i - 1, j - 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 0
    else:
        sum.append(0)
    if image_array[i - 1, j] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 1
    else:
        sum.append(0)
    if image_array[i - 1, j + 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 2
    else:
        sum.append(0)
    if image_array[i, j - 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 3
    else:
        sum.append(0)
    if image_array[i, j + 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 4
    else:
        sum.append(0)
    if image_array[i + 1, j - 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 5
    else:
        sum.append(0)
    if image_array[i + 1, j] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 6
    else:
        sum.append(0)
    if image_array[i + 1, j + 1] > image_array[i, j]:
        sum.append(1)
        num += 2 ** 7
    else:
        sum.append(0)
    return sum, num

 Nota (1) con diagrama

3. Gire continuamente la secuencia binaria para obtener el valor decimal mínimo de la secuencia binaria

# 获取二进制序列进行不断环形旋转得到新的二进制序列的最小十进制值
def get_min_for_revolve(self, arr):
    values = []
    circle = arr
    circle.extend(arr)
    for i in range(0, 8):
        j = 0
        sum = 0
        bit_num = 0
        while j < 8:
            sum += circle[i + j] << bit_num
            bit_num += 1
            j += 1
        values.append(sum)
    return min(values)

 El arr entrante es la suma en calute_basic_lbp, una secuencia binaria, y circle.extend (arr) es agregar la misma secuencia después de la secuencia del círculo, de modo que cada 8 elementos se recorren como un grupo, y después de recorrer ocho grupos, puede ver El resultado es que la secuencia gira constantemente y finalmente vuelve a la disposición de la secuencia original. El ciclo while calcula el número decimal de cada secuencia binaria, lo agrega a la lista de valores y devuelve el número decimal más pequeño. (<< es un operador de desplazamiento de bit a la izquierda, la función es desplazar el valor a la izquierda bit_num, si el valor de circle[i+j] es 3, bit_num es 3, entonces esta línea de código aumentará el valor de sum por 24)

4. Cree un diccionario de 36 características en modo de rotación invariable

def __init__(self):
    # revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典
    self.revolve_map = {0: 0, 1: 1, 3: 2, 5: 3, 7: 4, 9: 5, 11: 6, 13: 7, 15: 8, 17: 9, 19: 10, 21: 11, 23: 12, 25: 13,
                        27: 14, 29: 15, 31: 16, 37: 17, 39: 18, 43: 19, 45: 20, 47: 21, 51: 22, 53: 23, 55: 24, 59: 25,
                        61: 26, 63: 27, 85: 28, 87: 29, 91: 30, 95: 31, 111: 32, 119: 33, 127: 34, 255: 35}

 Después de que el número binario de ocho bits se rota continuamente, solo hay 36 tipos de decimales, por lo que estos 36 tipos de valores decimales se utilizan como claves del diccionario, y los valores correspondientes a las claves son valores de píxeles. (0~35)

5. Código completo

import numpy as np
import cv2
from PIL import Image
from pylab import *

class LBP:
    def __init__(self):
        # revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典
        self.revolve_map = {0: 0, 1: 1, 3: 2, 5: 3, 7: 4, 9: 5, 11: 6, 13: 7, 15: 8, 17: 9, 19: 10, 21: 11, 23: 12, 25: 13, 27: 14, 29: 15, 31: 16, 37: 17, 39: 18, 43: 19, 45: 20, 47: 21, 51: 22, 53: 23,55: 24,59: 25, 61: 26, 63: 27, 85: 28, 87: 29, 91: 30, 95: 31, 111: 32, 119: 33, 127: 34, 255: 35}

    # 图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较
    # 比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列
    def calute_basic_lbp(self, image_array, i, j):
        sum = []
        num = 0
        if image_array[i - 1, j - 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 0
        else:
            sum.append(0)
        if image_array[i - 1, j] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 1
        else:
            sum.append(0)
        if image_array[i - 1, j + 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 2
        else:
            sum.append(0)
        if image_array[i, j - 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 3
        else:
            sum.append(0)
        if image_array[i, j + 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 4
        else:
            sum.append(0)
        if image_array[i + 1, j - 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 5
        else:
            sum.append(0)
        if image_array[i + 1, j] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 6
        else:
            sum.append(0)
        if image_array[i + 1, j + 1] > image_array[i, j]:
            sum.append(1)
            num += 2 ** 7
        else:
            sum.append(0)
        return sum, num

    # 获取二进制序列进行不断环形旋转得到新的二进制序列的最小十进制值
    def get_min_for_revolve(self, arr):
        values = []
        circle = arr
        circle.extend(arr)
        for i in range(0, 8):
            j = 0
            sum = 0
            bit_num = 0
            while j < 8:
                sum += circle[i + j] << bit_num
                bit_num += 1
                j += 1
            values.append(sum)
        return min(values)

    # 获取图像的LBP旋转不变模式特征
    def lbp_revolve(self, image_array):
        revolve_array = np.zeros(image_array.shape, np.uint8)
        width = image_array.shape[0]
        height = image_array.shape[1]
        for i in range(1, width - 1):
            for j in range(1, height - 1):
                sum = self.calute_basic_lbp(image_array, i, j)[0]
                revolve_key = self.get_min_for_revolve(sum)
                revolve_array[i, j] = self.revolve_map[revolve_key]
        return revolve_array

    # 绘制指定维数和范围的图像灰度归一化统计直方图
    def show_hist(self, img_array, im_bins, im_range):
        # 直方图的x轴是灰度值,y轴是图片中具有同一个灰度值的点的数目, [img_array]原图像图像格式为uint8或float32,[0]0表示灰度,None无掩膜
        hist = cv2.calcHist([img_array], [0], None, im_bins, im_range)
        hist = cv2.normalize(hist, hist).flatten()  # 对计算出来的直方图数据进行归一化处理,并将结果扁平化为1D数组
        # print(hist)
        plt.plot(hist, color='r')
        plt.xlim(im_range)  # 设置X轴的取值范围
        plt.show()

    # 绘制图像旋转不变LBP特征的归一化统计直方图
    def show_revolve_hist(self, img_array):
        self.show_hist(img_array, [36], [0, 36])

    # 显示图像
    def show_image(self, image_array):
        plt.imshow(image_array, cmap='Greys_r')
        plt.show()

if __name__ == '__main__':
    image = cv2.imread('F:/out_picture/train/001.jpg')
    image_array = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    lbp = LBP()
    plt.imshow(image_array, cmap='Greys_r')  # 去掉参数就是热量图了
    plt.title('Original')
    plt.show()

    #获取图像旋转不变LBP特征,并显示其统计直方图与特征图像
    revolve_array = lbp.lbp_revolve(image_array)
    lbp.show_revolve_hist(revolve_array)
    lbp.show_image(revolve_array)


3. Resumen

        La extracción de características del modo invariante de rotación LBP es un poco más problemática que la extracción de características del modo original, principalmente a través de la rotación continua de la secuencia binaria de características del modo original para obtener su número decimal mínimo y usarlo como un valor de característica, y en 3 *3 En la vecindad de píxeles, compare el píxel central con los 8 píxeles circundantes para obtener que el número decimal mínimo de la secuencia binaria sea solo 36, por lo que mientras estos 36 modos estén claros, la extracción de las características del modo invariable de rotación LBP es básicamente resuelto

Si hay algún error, por favor corrígeme!

Supongo que te gusta

Origin blog.csdn.net/qq_66036911/article/details/130330313
Recomendado
Clasificación