python实现LBP-TOP代码部分问题

LBP-TOP 是 LBP 从二维空间到三维空间的拓展,LBP-TOP 的全称为: local binary patterns from three orthogonal planes

欢迎关注公众号:七只的Coding日志,更多内容链接

随着LBP的改进和优化,衍生出许多其它的算子:

(1)圆形LBP算子:
基本的 LBP算子的最大缺陷在于它只覆盖了一个固定半径范围内的小区域,这显然不能满足不同尺寸和频率纹理的需要。为了适应不同尺度的纹理特征,并达到灰度和旋转不变性的要求,Ojala等对 LBP算子进行了改进,将 3×3邻域扩展到任意邻域,并用圆形邻域代替了正方形邻域,改进后的 LBP算子允许在半径为 R 的圆形邻域内有任意多个像素点。从而得到了诸如半径为R的圆形区域内含有P个采样点的LBP算子;

圆形LBP算子

(2)LBP旋转不变模式
从 LBP 的定义可以看出,LBP 算子是灰度不变的,但却不是旋转不变的。图像的旋转就会得到不同的 LBP值。Maenpaa等人又将 LBP算子进行了扩展,提出了具有旋转不变性的 LBP算子,即不断旋转圆形邻域得到一系列初始定义的 LBP值,取其最小值作为该邻域的 LBP值。

LBP旋转不变模式

(3)LBP等价模式
一个LBP算子可以产生不同的二进制模式,对于半径为R的圆形区域内含有P个采样点的LBP算子将会产生P2种模式。很显然,随着邻域集内采样点数的增加,二进制模式的种类是急剧增加的。例如:5×5邻域内20个采样点,有220=1,048,576种二进制模式。如此多的二值模式无论对于纹理的提取还是对于纹理的识别、分类及信息的存取都是不利的。同时,过多的模式种类对于纹理的表达是不利的。例如,将LBP算子用于纹理分类或人脸识别时,常采用LBP模式的统计直方图来表达图像的信息,而较多的模式种类将使得数据量过大,且直方图过于稀疏。因此,需要对原始的LBP模式进行降维,使得数据量减少的情况下能最好的代表图像的信息。

LBP等价模式

python实现LBP特征点计算

import cv2
import numpy as np


def olbp(src):
    dst = np.zeros(src.shape,dtype=src.dtype)
    for i in range(1,src.shape[0]-1):
        for j in range(1,src.shape[1]-1):
            pass
            center = src[i][j]
            code = 0;
            code |= (src[i-1][j-1] >= center) << 7;
            code |= (src[i-1][j  ] >= center) << 6;
            code |= (src[i-1][j+1] >= center) << 5;
            code |= (src[i  ][j+1] >= center) << 4;
            code |= (src[i+1][j+1] >= center) << 3;
            code |= (src[i+1][j  ] >= center) << 2;
            code |= (src[i+1][j-1] >= center) << 1;
            code |= (src[i  ][j-1] >= center) << 0;

            dst[i-1][j-1]= code;
    return dst


lena = cv2.imread('2.jpg')
cv2.namedWindow('lena')
cv2.imshow('lena', lena)
#cv2.waitKey(0)

gray = cv2.cvtColor(lena,cv2.COLOR_RGB2GRAY)
x = olbp(gray)
cv2.namedWindow('olbp')
cv2.imshow('olbp', x)
cv2.waitKey(0)

LBP图片展示:

原图
特征点图

对LBP进行简单介绍后,我们可以了解到,LBP-TOP相对于LBP来说增加时间T维度,从原来的X-Y平面增加到X-Y,X-T,Y-T三个平面。

LBP-TOP feature
scan all the pixels and compute their LBP patterns on the XY, XT and YT plane respectively

本次主要是以目前奥卢大学发布的源代码作为解释依据,官网下载地址,首先,建立X,Y,T空间坐标系,如上图所示。

目前ME特征提取当中,LBP-TOP是比较常用的方法,在一段视频序列中,会有许多帧图片,这对于人脸表情来说,会存在着许多时间序列特征。

想要得到相应的直方图,首先,我们需要确定领域像素点个数。在Guoying Zhao, Matti Pietikainen, "Dynamic texture recognition using local binary patterns with an application to facial expressions," IEEE Transactions on Pattern Analysis and Machine Intelligence, 2007, 29(6):915-928.这篇论文当中所提到,一般领域点可以取4,8,16,24,但8是最好的选择,如下图最左边取得8个像素点,半径R=1:

image.png

在X-Y平面中我们可以定半径R(x-y)=1,取八个像素点;在X-T和Y-T平面上就不一样啦!拿X-T平面举例(人脸图像红色划线部分)

        %% XTNeighborPoints:邻域像素点个数
        %% FxRadius:X轴上半径
        %% TInterval :T轴上半径,也是指前后距当前帧图片的帧数。

        %% In XT plane
        BasicLBP = 0;
        FeaBin = 0;
        for p = 0 : XTNeighborPoints - 1
              X = floor(xc + FxRadius * cos((2 * pi * p) / XTNeighborPoints) + 0.5);
              Z = floor(i + TInterval * sin((2 * pi * p) / XTNeighborPoints) + 0.5);
                    
              CurrentVal = VolData(yc, X, Z);
                    
              if CurrentVal >= CenterVal
                    BasicLBP = BasicLBP + 2 ^ FeaBin;
              end
              FeaBin = FeaBin + 1;
       end

一个for 循环将所有附近的像素点遍历,并进行相应的LBP计算。可知道的是,这里取邻域像素点并不一定是一个圆,恰恰却是一个椭圆。

image.png

当搞懂基本的运算过程后,运用python实现LBP-TOP算法。

def LBP_TOP(VolData, xRadius = 1, yRadius = 1, tInterval = 4, NeighborPoints = [8, 8, 8], TimeLength = 4, BorderLength = 1):
    # VolData:一段表情序列图像集
    # xRadius:在X轴上半径,默认值为1
    # yRadius:在Y轴上半径,默认值为1
    # tInterval:在T轴上半径,默认值为4
    # NeighborPoints:在XY,XT,YT平面上所选取的邻域像素点个数,默认值为8,8,8

    length, height, width = VolData.shape

    XYNeighborPoints = NeighborPoints[0]
    XTNeighborPoints = NeighborPoints[1]
    YTNeighborPoints = NeighborPoints[2]

    nDim = 2 ** (YTNeighborPoints)
    Histogram = np.zeros((3, nDim), float)

    for t in range(TimeLength, length - TimeLength):
        for yc in range(BorderLength, height - BorderLength):
            for xc in range(BorderLength, width - BorderLength):
                CenterVal = VolData[t, yc, xc]
                
                # XY平面上
                BasicLBP = 0
                FeaBin = 0

                for p in range(0, XYNeighborPoints):
                    X = int(xc + xRadius * math.cos((2 * math.pi * p)/XYNeighborPoints) + 0.5)
                    Y = int(yc - yRadius * math.sin((2 * math.pi * p)/XYNeighborPoints) + 0.5)
                    
                    CurrentVal = VolData[t, Y, X]

                    if CurrentVal >= CenterVal:
                        BasicLBP += 2 ** FeaBin

                    FeaBin += 1

                Histogram[0, BasicLBP] = Histogram[0, BasicLBP] + 1 #计数


                # XT平面上
                BasicLBP = 0
                FeaBin = 0

                for p in range(0, XTNeighborPoints):
                    X = int(xc + xRadius * math.cos((2 * math.pi * p) / XTNeighborPoints) + 0.5)
                    Z = int(t + tInterval * math.sin((2 * math.pi * p) / XTNeighborPoints) + 0.5)
                    
                    CurrentVal = VolData[Z, yc, X]

                    if CurrentVal >= CenterVal:
                        BasicLBP += 2 ** FeaBin

                    FeaBin += 1

                Histogram[1, BasicLBP] = Histogram[1, BasicLBP] + 1

                # YT平面上
                BasicLBP = 0
                FeaBin = 0

                for p in range(0, YTNeighborPoints):
                    Y = int(yc - yRadius * math.cos((2 * math.pi * p) / YTNeighborPoints) + 0.5)
                    Z = int(t + tInterval * math.sin((2 * math.pi * p) / YTNeighborPoints) + 0.5)
                    
                    CurrentVal = VolData[Z, Y, xc]

                    if CurrentVal >= CenterVal:
                        BasicLBP += 2 ** FeaBin

                    FeaBin += 1

                Histogram[2, BasicLBP] = Histogram[2, BasicLBP] + 1
    # 规范化
    for j in range(0, 3):
        Histogram[j, :] = (Histogram[j, :] * 1.0) / sum(Histogram[j, :])
    return Histogram

如有错误,请评论区留言)还有部分后面更新。。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容