LBP特征计算程序

2024-01-29 09:59
文章标签 程序 计算 特征 lbp

本文主要是介绍LBP特征计算程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/hujingshuang/article/details/47292721

简介:

局部二值模式(Local Binary Pattern, LBP)是一种有效的纹理描述算子,它具有旋转不变性和灰度不变性的显著的有点。已经广泛的应用于纹理分类、纹理分割、人脸图像分析等领域。本文就LBP算法做简单的讲解,并在OpenCV中加以实现。

基本的LBP算子

局部二值模式是一种灰度范围内的纹理描述方式。算法的思想是利用结构化思想提取窗口特征,再利用统计化做最终整体特征的提取。

最初的LBP描述子算法步骤如下:

1、对图像中的所有点,以该点为中心,取3x3的邻域窗口;

2、8-邻域像素值与中心点像素值进行比较,大于或等于中心像素标记为1,否则标记为0;

3、将周围0-1序列,以一定的顺序排列,成一个8位的无符号的二进制数,转化成整数;

4、这个整数就是表征这个窗口的LBP值


以上,便是最基本的LBP算子。由于直接利用的灰度比较,所以其具有灰度不变性;但是,有两个很明显的缺点:

1、产生的二进制模式多;

2、不具有旋转不变性

为解决这两个问题,后人对LBP算法做了改进,后面会有介绍。

当然,上面的8-邻域并不是最好的,但是最基本的,在后面出现了诸如下图所示的邻域,1,2指的是半径,8,16指的是采样点数。


改进的LBP算子

LBP等价模式

      考察LBP算子的定义可知,一个LBP算子可以产生多种二进制模式(p个采样点)如:3x3邻域有p=8个采样点,则可得到2^8=256种二进制模式;5x5邻域有p=24个采样点,则可得到2^24=16777216种二进制模式,以此类推......。显然,过多的二进制模式无论对于纹理的提取还是纹理的识别、分类及信息存取都是不利的,在实际应用中不仅要求采用的算子尽量简单,同时也要考虑到计算速度、存储量大小等问题。因此需要对原始的LBP模式进行降维

      Ojala提出一种“等价模式”(Uniform Pattern)来对LBP算子进行降维,Ojala等认为图像中,某个局部二进制模式所对应的循环二进制数从0—>1从1—>0,最多有两次跳变,该局部二进制模式所对应的二进制就成为一个等价模式。如00000000,00111000,10001111,11111111等都是等价模式类。判断一个二进制模式是否为等价模式最简单的办法就是将LBP值与其循环移动一位后的值进行按位相与,计算得到的二进制数中1的个数,若个数小于或等于2,则是等价模式;否则,不是。出了等价模式以外的模式都归一一类,称为混合模式类。

       通过这种改进,二进制模式的种类大大减少,而不会丢失任何信息,模式种类由原来的2^p减少为p*(p-1)+2种。

       但等价模式代表了图像的边缘、斑点、角点等关键模式,等价模式占了总模式中的绝大多数,所以极大的降低了特征维度。利用这些等价模式和混合模式类直方图,能够更好地提取图像的本质特征。


(降维而不丢失了图像主要的信息,精华的部分!)

旋转不变的LBP算子

       由于LBP的二进制模式是以一定的方向、顺序进行编码的,所以当图像发生旋转时,按这种编码的话,LBP值会发生改变,因此是不具有旋转不变性的。Maenpaa等人提出了具有旋转不变性的LBP算子。

       解决办法是:不断旋转邻域得到一系列的LBP值,取其中最小值作为该邻域的LBP值。旋转过程实质上就是对二进制模式进行循环移位的过程。


      通过引入旋转不变的定义,使LBP算子更具鲁棒性。但这也是LBP算子丢失了方向信息。在很多场合,方向信息非常重要;然而,在纹理图像分析中,LBP依然被证明是有效的。

实验

opencv代码

通过定义model_rotationmodel_equivalent来进行等价模式和旋转不变性的实现。

[cpp]  view plain copy
在CODE上查看代码片 派生到我的代码片
  1. /***************************************** 
  2. Copyright (c) 2015 Jingshuang Hu 
  3.  
  4. @filename:intrins.cpp 
  5. @datetime:2015.08.05 
  6. @author:HJS 
  7. @e-mail:eleftheria@163.com 
  8. @blog:http://blog.csdn.net/hujingshuang 
  9. *****************************************/  
  10.   
  11. #include <iostream>  
  12. #include <opencv2/core/core.hpp>  
  13. #include <opencv2/highgui/highgui.hpp>  
  14. #include <opencv2/imgproc/imgproc.hpp>  
  15. #include "intrins.h"  
  16.   
  17. using namespace cv;  
  18. using namespace std;  
  19.   
  20. #define model_rotation  
  21. #define model_equivalent  
  22.   
  23. int main()  
  24. {  
  25.     Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);//灰度  
  26.     Mat pic = Mat::zeros(img.rows, img.cols, img.type());  
  27.     imshow("src", img);  
  28.     //p1    p2  p3  
  29.     //p8    p0  p4  
  30.     //p7    p6  p5  
  31.     for (int i = 1; i < img.rows - 1; i++)  
  32.     {  
  33.         for (int j = 1; j < img.cols - 1; j++)  
  34.         {  
  35.             uchar p[9];  
  36.   
  37.             p[0] = img.at<uchar>(i, j);//中心  
  38.             p[1] = img.at<uchar>(i - 1, j - 1);  
  39.             p[2] = img.at<uchar>(i - 1, j);  
  40.             p[3] = img.at<uchar>(i - 1, j + 1);  
  41.             p[4] = img.at<uchar>(i, j + 1);  
  42.             p[5] = img.at<uchar>(i + 1, j + 1);  
  43.             p[6] = img.at<uchar>(i + 1, j);  
  44.             p[7] = img.at<uchar>(i + 1, j - 1);  
  45.             p[8] = img.at<uchar>(i, j - 1);  
  46.               
  47.             uchar value = 0;//LBP值  
  48.             for (int k = 1; k <= 8; k++)  
  49.             {  
  50.                 value += (p[k] >= p[0]) << (8 - k);  
  51.             }  
  52. //等价模式  
  53. #ifdef model_equivalent  
  54.             uchar temp = _cror(value, 1);  
  55.             if(_mm_popcnt_u32(temp & value) > 2)//_mm_popcnt_u32计算二进制数1的个数  
  56.             {  
  57.                 pic.at<uchar>(i, j) = value;  
  58.             }  
  59. #else  
  60.             pic.at<uchar>(i, j) = value;  
  61. #endif  
  62. //旋转不变  
  63. #ifdef model_rotation  
  64.             uchar rot[8];  
  65.             _rota(value, rot);  
  66.             pic.at<uchar>(i, j) = _min(rot);  
  67. #endif  
  68.         }  
  69.     }  
  70.     imshow("LBP_equ_rot", pic);  
  71.     waitKey();  
  72.   
  73.   
  74.     return 0;  
  75. }  

其中intrins.hintrins.cpp是循环移位及查找最小值的源代码。

intrins.h

[cpp]  view plain copy
在CODE上查看代码片 派生到我的代码片
  1. /***************************************** 
  2. Copyright (c) 2015 Jingshuang Hu 
  3.  
  4. @filename:intrins.cpp 
  5. @datetime:2015.08.05 
  6. @author:HJS 
  7. @e-mail:eleftheria@163.com 
  8. @blog:http://blog.csdn.net/hujingshuang 
  9. *****************************************/  
  10.   
  11. #ifndef __INTRINS_H__  
  12. #define __INTRINS_H__  
  13.   
  14. #include <cv.h>  
  15.   
  16. using namespace std;  
  17.   
  18. uchar _crol(uchar tmp, uchar n);  
  19. uchar _crol_bit(uchar tmp);  
  20. uchar _cror(uchar tmp, uchar n);  
  21. uchar _cror_bit(uchar tmp);  
  22. void _rota(uchar tmp, uchar *temp);  
  23. uchar _min(uchar *tmp);  
  24.   
  25. #endif  
intrins.cpp

[cpp]  view plain copy
在CODE上查看代码片 派生到我的代码片
  1. /***************************************** 
  2. Copyright (c) 2015 Jingshuang Hu 
  3.  
  4. @filename:intrins.cpp 
  5. @datetime:2015.08.05 
  6. @author:HJS 
  7. @e-mail:eleftheria@163.com 
  8. @blog:http://blog.csdn.net/hujingshuang 
  9. *****************************************/  
  10.   
  11. #include "intrins.h"  
  12.   
  13. //循环左移n位  
  14. uchar _crol(uchar tmp, uchar n)  
  15. {  
  16.     while(n--)  
  17.     {  
  18.         tmp = _crol_bit(tmp);  
  19.     }  
  20.     return tmp;  
  21. }  
  22. //循环左移1位  
  23. uchar _crol_bit(uchar tmp)  
  24. {  
  25.     return (tmp << 1) | (tmp >> 7);  
  26. }  
  27. //循环右移n位  
  28. uchar _cror(uchar tmp, uchar n)  
  29. {  
  30.     while(n--)  
  31.     {  
  32.         tmp = _cror_bit(tmp);  
  33.     }  
  34.     return tmp;  
  35. }  
  36. //循环右移1位  
  37. uchar _cror_bit(uchar tmp)  
  38. {  
  39.     return (tmp >> 1) | (tmp << 7);  
  40. }  
  41. //循环移位(旋转)  
  42. void _rota(uchar tmp, uchar *temp)  
  43. {  
  44.     for (int i = 0; i < 8; i++)  
  45.     {  
  46.         *temp = _cror(tmp, i);  
  47.         temp++;  
  48.     }  
  49. }  
  50. //找到最小值  
  51. uchar _min(uchar *tmp)  
  52. {  
  53.     uchar min = *tmp;  
  54.     for (int i = 0; i < 8; i++)  
  55.     {  
  56.         tmp++;  
  57.         if (min > *tmp)  
  58.         {  
  59.             min = *tmp;  
  60.         }  
  61.     }  
  62.     return min;  
  63. }  

结果:

依次是:原图、等价模式、旋转不变、等价+旋转不变(注:此处等价模式未进行任何的等价处理)

参考文献:

1、黄菲菲,基于LBP的人脸识别研究[M],2009.

2、程雪峰,基于LBP特征的人脸识别算法研究[M],2014.

这篇关于LBP特征计算程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/656551

相关文章

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

跨系统环境下LabVIEW程序稳定运行

在LabVIEW开发中,不同电脑的配置和操作系统(如Win11与Win7)可能对程序的稳定运行产生影响。为了确保程序在不同平台上都能正常且稳定运行,需要从兼容性、驱动、以及性能优化等多个方面入手。本文将详细介绍如何在不同系统环境下,使LabVIEW开发的程序保持稳定运行的有效策略。 LabVIEW版本兼容性 LabVIEW各版本对不同操作系统的支持存在差异。因此,在开发程序时,尽量使用

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

这些心智程序你安装了吗?

原文题目:《为什么聪明人也会做蠢事(四)》 心智程序 大脑有两个特征导致人类不够理性,一个是处理信息方面的缺陷,一个是心智程序出了问题。前者可以称为“认知吝啬鬼”,前几篇文章已经讨论了。本期主要讲心智程序这个方面。 心智程序这一概念由哈佛大学认知科学家大卫•帕金斯提出,指个体可以从记忆中提取出的规则、知识、程序和策略,以辅助我们决策判断和解决问题。如果把人脑比喻成计算机,那心智程序就是人脑的