LBP特征

  • https://blog.csdn.net/q123456789098/article/details/52748918
  • https://blog.csdn.net/zouxy09/article/details/7929531

在这里插入图片描述

LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。

原始的LBP算子定义为在3*3的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数(通常转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。如下图所示:

在这里插入图片描述
Maenpaa等人又将 LBP算子进行了扩展,提出了具有旋转不变性的 LBP 算子,即不断旋转圆形邻域得到一系列初始定义的 LBP值,取其最小值作为该邻域的 LBP 值。
图 2.5 给出了求取旋转不变的 LBP 的过程示意图,图中算子下方的数字表示该算子对应的 LBP值,图中所示的 8 种 LBP模式,经过旋转不变的处理,最终得到的具有旋转不变性的 LBP值为 15。也就是说,图中的 8种 LBP 模式对应的旋转不变的 LBP模式都是 00001111。

在这里插入图片描述
例如:一幅100*100像素大小的图片,划分为10*10=100个子区域(可以通过多种方式来划分区域),每个子区域的大小为10*10像素;在每个子区域内的每个像素点,提取其LBP特征,然后,建立统计直方图;这样,这幅图片就有10*10个子区域,也就有了10*10个统计直方图,利用这10*10个统计直方图,就可以描述这幅图片了。之后,我们利用各种相似性度量函数,就可以判断两幅图像之间的相似性了;

3、对LBP特征向量进行提取的步骤

(1)首先将检测窗口划分为16×16的小区域(cell);

(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;

(3)然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理。

(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;

然后便可利用SVM或者其他机器学习算法进行分类了。

代码实现

# @Time: 2021/6/10 11:29 
# @Author: wucong
# @File: computer_lbp.py 
# @Software: PyCharm
# @Version: win10 Python 3.7.6
# @Version: torch 1.8.1+cu111 torchvision 0.9.1+cu111
# @Version: tensorflow 2.4.1+cu111  keras 2.4.3
# @Describe:
"""
- https://blog.csdn.net/q123456789098/article/details/52748918
- https://blog.csdn.net/zouxy09/article/details/7929531

LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;
它具有旋转不变性和灰度不变性等显著的优点。
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import normalize
from numba import jit
from scipy import signal
import time

# from skimage.feature import local_binary_pattern as lbp

def get_lbp_value(str1:str,rotation:bool):
    if rotation:
        tmp=[]
        for i in range(8):
            tmp.append(int(str1, 2))
            str1 = str1[1:]+str1[0]
        return min(tmp)
    else:
        return int(str1,2) # 转成10进制

def get_lbp_img(img:np.array,ksize=3,h=64,w=64,rotation=True):
    img = np.pad(img,[[1,1],[1,1]],'constant',constant_values=0)
    new_img = img.copy()
    for i in range(1,h+1):
        for j in range(1,w+1):
            lbp_list = []
            p = ksize//2
            v = img[i,j]
            lbp_list.append(str((img[i-p,j-p]>v).astype(int)))
            lbp_list.append(str((img[i-p,j]>v).astype(int)))
            lbp_list.append(str((img[i-p,j+p]>v).astype(int)))
            lbp_list.append(str((img[i,j+p]>v).astype(int)))
            lbp_list.append(str((img[i+p,j+p]>v).astype(int)))
            lbp_list.append(str((img[i+p,j]>v).astype(int)))
            lbp_list.append(str((img[i+p,j-p]>v).astype(int)))
            lbp_list.append(str((img[i,j-p]>v).astype(int)))

            # 加入旋转不变性 取最小值
            lbp_str = "".join(lbp_list)

            new_img[i,j] = get_lbp_value(lbp_str,rotation)

    return new_img[1:-1,1:-1]


def lbp(img:np.array,cell_size,stride=0,bins=64,h=64,w=64,rotation=True):
    """

    Args:
        img: 默认是 BGR格式
        cell_size:
        stride: >=cell_size时 每个cell间不重叠 ;否则重叠
        bins: 0 表示不做统计;否则 做统计 [0,256] 推荐使用 统计
        h: resize 后的 高
        w:  resize 后的 宽

    Returns: lbp特征

    """

    # 1.灰度化
    if img.ndim > 2: img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = cv2.resize(img, (w, h))
    img = get_lbp_img(img,3,h,w,rotation)

    if stride == 0: stride=cell_size
    feature = []
    for i in range(0,h-cell_size,stride):
        for j in range(0,w-cell_size,stride):
            timg = img[i:i+cell_size,j:j+cell_size] # 1个cell
            if bins == 0: # 不做统计
                # feature.append(timg)
                feature.append(normalize(np.array(timg.flatten())[None])[0])
            else:
                interval = 256/bins
                hist = [0]*bins
                for px in timg.flatten():
                    hist[int(px//interval)] += 1

                # 归一化
                hist = normalize(np.array(hist)[None])[0]
                feature.append(hist)

    return np.stack(feature).reshape(-1)

if __name__=="__main__":
    start = time.time()
    img = cv2.imread('./6_36_1.jpg')
    feature = lbp(img,cell_size=10,stride=3,bins=0)
    end = time.time()
    print(feature.shape,'cost time:%.5f'%(end-start))
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值