VLFeat库->LBP特征源码解析
2014-06-16 15:15
351 查看
本来想直接调用VLFeat里面的LBP特征提取函数,所以就看了一下其函数实现的方式,如下:
lbp.h
/** @file lbp.h
** @brief Local Binary Patterns (LBP) descriptor (@ref lbp)
** @author Andrea Vedaldi
**/
/*
Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
All rights reserved.
This file is part of the VLFeat library and is made available under
the terms of the BSD license (see the COPYING file).
*/
#ifndef VL_LBP_H
#define VL_LBP_H
#include "generic.h"
/** @brief Type of quantization for the LBP descriptors
** @see @ref lbp-quantization
**/
typedef enum _VlLbpMappingType
{
VlLbpUniform /**< Uniform local binary patterns. */
} VlLbpMappingType ;
/** @brief Local Binary Pattern extractor */
typedef struct VlLbp_
{
vl_size dimension ;
vl_uint8 mapping [256] ;
vl_bool transposed ;
} VlLbp ;
//new lbp
VL_EXPORT VlLbp * vl_lbp_new(VlLbpMappingType type, vl_bool transposed) ;
//delete lbp
VL_EXPORT void vl_lbp_delete(VlLbp * self) ;
VL_EXPORT void vl_lbp_process(VlLbp * self,
float * features,
float * image, vl_size width, vl_size height,
vl_size cellSize) ;
VL_EXPORT vl_size vl_lbp_get_dimension(VlLbp * self) ;
/* VL_LBP_H */
#endif
lbp.cpp里面的LBP特征提取函数如下
VL_EXPORT void
vl_lbp_process (VlLbp * self,
float * features,
float * image, vl_size width, vl_size height,
vl_size cellSize)
{
vl_size cwidth = width / cellSize;
vl_size cheight = height / cellSize ;
vl_size cstride = cwidth * cheight ;
vl_size cdimension = vl_lbp_get_dimension(self) ;
vl_index x,y,cx,cy,k,bin ;
#define at(u,v) (*(image + width * (v) + (u)))
#define to(u,v,w) (*(features + cstride * (w) + cwidth * (v) + (u)))
/* clear the output buffer */
memset(features, 0, sizeof(float)*cdimension*cstride) ;
/* accumulate pixel-level measurements into cells */
for (y = 1 ; y < (signed)height - 1 ; ++y) {
float wy1 = (y + 0.5f) / (float)cellSize - 0.5f ;
int cy1 = (int) vl_floor_f(wy1) ;
int cy2 = cy1 + 1 ;
float wy2 = wy1 - (float)cy1 ;
wy1 = 1.0f - wy2 ;
if (cy1 >= (signed)cheight) continue ;
for (x = 1 ; x < (signed)width - 1; ++x) {
float wx1 = (x + 0.5f) / (float)cellSize - 0.5f ;
int cx1 = (int) vl_floor_f(wx1) ;
int cx2 = cx1 + 1 ;
float wx2 = wx1 - (float)cx1 ;
wx1 = 1.0f - wx2 ;
if (cx1 >= (signed)cwidth) continue ;
{
int unsigned bitString = 0 ;
float center = at(x,y) ;
//邻域8个点与中心点比较得到8位二进制的LBP特征向量
if(at(x+1,y+0) > center) bitString |= 0x1 << 0; /* E */
if(at(x+1,y+1) > center) bitString |= 0x1 << 1; /* SE */
if(at(x+0,y+1) > center) bitString |= 0x1 << 2; /* S */
if(at(x-1,y+1) > center) bitString |= 0x1 << 3; /* SW */
if(at(x-1,y+0) > center) bitString |= 0x1 << 4; /* W */
if(at(x-1,y-1) > center) bitString |= 0x1 << 5; /* NW */
if(at(x+0,y-1) > center) bitString |= 0x1 << 6; /* N */
if(at(x+1,y-1) > center) bitString |= 0x1 << 7; /* NE */
bin = self->mapping[bitString] ;
}
if ((cx1 >= 0) & (cy1 >=0)) {
to(cx1,cy1,bin) += wx1 * wy1;
}
if ((cx2 < (signed)cwidth) & (cy1 >=0)) {
to(cx2,cy1,bin) += wx2 * wy1 ;
}
if ((cx1 >= 0) & (cy2 < (signed)cheight)) {
to(cx1,cy2,bin) += wx1 * wy2 ;
}
if ((cx2 < (signed)cwidth) & (cy2 < (signed)cheight)) {
to(cx2,cy2,bin) += wx2 * wy2 ;
}
} /* x */
} /* y */
/* normalize cells */
for (cy = 0 ; cy < (signed)cheight ; ++cy) {
for (cx = 0 ; cx < (signed)cwidth ; ++ cx) {
float norm = 0 ;
for (k = 0 ; k < (signed)cdimension ; ++k) {
norm += features[k * cstride] ;
}
norm = sqrtf(norm) + 1e-10f; ;
for (k = 0 ; k < (signed)cdimension ; ++k) {
features[k * cstride] = sqrtf(features[k * cstride]) / norm ;
}
features += 1 ;
}
} /* next cell to normalize */
}
从上可以看出该代码对LBP特征向量进行提取的步骤
(1)首先将检测窗口划分为n×n的小区域(cell);
(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;
(3)然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理。
(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;
最原始的LBP特征提取的代码。
lbp.h
/** @file lbp.h
** @brief Local Binary Patterns (LBP) descriptor (@ref lbp)
** @author Andrea Vedaldi
**/
/*
Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
All rights reserved.
This file is part of the VLFeat library and is made available under
the terms of the BSD license (see the COPYING file).
*/
#ifndef VL_LBP_H
#define VL_LBP_H
#include "generic.h"
/** @brief Type of quantization for the LBP descriptors
** @see @ref lbp-quantization
**/
typedef enum _VlLbpMappingType
{
VlLbpUniform /**< Uniform local binary patterns. */
} VlLbpMappingType ;
/** @brief Local Binary Pattern extractor */
typedef struct VlLbp_
{
vl_size dimension ;
vl_uint8 mapping [256] ;
vl_bool transposed ;
} VlLbp ;
//new lbp
VL_EXPORT VlLbp * vl_lbp_new(VlLbpMappingType type, vl_bool transposed) ;
//delete lbp
VL_EXPORT void vl_lbp_delete(VlLbp * self) ;
VL_EXPORT void vl_lbp_process(VlLbp * self,
float * features,
float * image, vl_size width, vl_size height,
vl_size cellSize) ;
VL_EXPORT vl_size vl_lbp_get_dimension(VlLbp * self) ;
/* VL_LBP_H */
#endif
lbp.cpp里面的LBP特征提取函数如下
VL_EXPORT void
vl_lbp_process (VlLbp * self,
float * features,
float * image, vl_size width, vl_size height,
vl_size cellSize)
{
vl_size cwidth = width / cellSize;
vl_size cheight = height / cellSize ;
vl_size cstride = cwidth * cheight ;
vl_size cdimension = vl_lbp_get_dimension(self) ;
vl_index x,y,cx,cy,k,bin ;
#define at(u,v) (*(image + width * (v) + (u)))
#define to(u,v,w) (*(features + cstride * (w) + cwidth * (v) + (u)))
/* clear the output buffer */
memset(features, 0, sizeof(float)*cdimension*cstride) ;
/* accumulate pixel-level measurements into cells */
for (y = 1 ; y < (signed)height - 1 ; ++y) {
float wy1 = (y + 0.5f) / (float)cellSize - 0.5f ;
int cy1 = (int) vl_floor_f(wy1) ;
int cy2 = cy1 + 1 ;
float wy2 = wy1 - (float)cy1 ;
wy1 = 1.0f - wy2 ;
if (cy1 >= (signed)cheight) continue ;
for (x = 1 ; x < (signed)width - 1; ++x) {
float wx1 = (x + 0.5f) / (float)cellSize - 0.5f ;
int cx1 = (int) vl_floor_f(wx1) ;
int cx2 = cx1 + 1 ;
float wx2 = wx1 - (float)cx1 ;
wx1 = 1.0f - wx2 ;
if (cx1 >= (signed)cwidth) continue ;
{
int unsigned bitString = 0 ;
float center = at(x,y) ;
//邻域8个点与中心点比较得到8位二进制的LBP特征向量
if(at(x+1,y+0) > center) bitString |= 0x1 << 0; /* E */
if(at(x+1,y+1) > center) bitString |= 0x1 << 1; /* SE */
if(at(x+0,y+1) > center) bitString |= 0x1 << 2; /* S */
if(at(x-1,y+1) > center) bitString |= 0x1 << 3; /* SW */
if(at(x-1,y+0) > center) bitString |= 0x1 << 4; /* W */
if(at(x-1,y-1) > center) bitString |= 0x1 << 5; /* NW */
if(at(x+0,y-1) > center) bitString |= 0x1 << 6; /* N */
if(at(x+1,y-1) > center) bitString |= 0x1 << 7; /* NE */
bin = self->mapping[bitString] ;
}
if ((cx1 >= 0) & (cy1 >=0)) {
to(cx1,cy1,bin) += wx1 * wy1;
}
if ((cx2 < (signed)cwidth) & (cy1 >=0)) {
to(cx2,cy1,bin) += wx2 * wy1 ;
}
if ((cx1 >= 0) & (cy2 < (signed)cheight)) {
to(cx1,cy2,bin) += wx1 * wy2 ;
}
if ((cx2 < (signed)cwidth) & (cy2 < (signed)cheight)) {
to(cx2,cy2,bin) += wx2 * wy2 ;
}
} /* x */
} /* y */
/* normalize cells */
for (cy = 0 ; cy < (signed)cheight ; ++cy) {
for (cx = 0 ; cx < (signed)cwidth ; ++ cx) {
float norm = 0 ;
for (k = 0 ; k < (signed)cdimension ; ++k) {
norm += features[k * cstride] ;
}
norm = sqrtf(norm) + 1e-10f; ;
for (k = 0 ; k < (signed)cdimension ; ++k) {
features[k * cstride] = sqrtf(features[k * cstride]) / norm ;
}
features += 1 ;
}
} /* next cell to normalize */
}
从上可以看出该代码对LBP特征向量进行提取的步骤
(1)首先将检测窗口划分为n×n的小区域(cell);
(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;
(3)然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理。
(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;
最原始的LBP特征提取的代码。
相关文章推荐
- FreeRTOS源码解析 -> vTaskStartScheduler()
- 安装源码包 httpd-2.2.22.tar.bz2 php-5.4.10.tar.bz2 使网站可以解析以下内容 <?php phpinfo(); ?>
- FreeRTOS源码解析 -> vTaskDelayUntil()
- LBP原理加源码解析
- AFNetworking2.0源码解析<二>
- opencv源码解析之(3):特征点检查前言1
- FreeRTOS源码解析 -> xTaskCreate()
- AFNetworking2.0源码解析<一>
- Volley 源码解析<转>
- AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】
- <自己动手写操作系统>第三章pmtest7源码解析——检测系统内存
- <自己动手写操作系统>第三章——pmtest3源码解析:使用LDT
- FreeRTOS源码解析 -> vTaskDelete()
- AFNetworking2.0源码解析<二>
- AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】
- AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】
- 特征提取->LBP特征(1)
- FreeRTOS源码解析 -> vTaskResume()
- train_cascade 源码阅读之LBP特征
- Android小项目之--应用解析 Content Provider->内容提供商(附源码)