【OpenCV 例程200篇】227. 特征描述之 LBP 纹理特征算子

『youcans 的 OpenCV 例程200篇 - 总目录』

【youcans 的 OpenCV 例程200篇】227. 特征描述之 LBP 纹理特征算子


特征通常是针对于图像中的某个目标而言的。

针对目标所在区域的特征描述符(Region descriptors),称为区域特征描述子。


4.2 纹理特征之统计直方图

纹理体现了物体表面的具有缓慢变化或者周期性变化的表面结构组织排列属性。纹理特征描述了图像或图像区域所对应景物的表面性质。

纹理与尺度密切相关,一般仅呈现在特定尺度上,对纹理的识别要在恰当的尺度上进行。 纹理特征不是基于像素点的特征,而是一种基于像素区域的统计特性。因此,纹理能用来描述不同的图像区域。

纹理特征具有三个性质:

  • 某种局部序列性不断重复;
  • 非随机排列;
  • 纹理区域内大致为均匀的统一体。

纹理特征通常具有旋转不变性,在模式匹配中对噪声有较强的抵抗能力。

描述图像中的纹理区域,要基于区域尺度、可分辨灰度元素的数目以及这些灰度元素的相互关系等。


4.2.1 LBP 纹理特征算子

局部二值模式(LBP,Local binary patterns)是一种用来描述图像局部纹理特征的算子,它具有旋转不变性和灰度不变性的优点 。 LBP 特征计算简单、效果较好,在计算机视觉领域得到了广泛的应用。

LBP 通过对邻域像素进行阈值处理并以二进制数表示来标记像素,所得到的灰度图像反映了图像中的纹理。

原始的 LBP 算子定义在 3×3 的窗口内,以窗口中心像素为阈值,与相邻的 8 个像素的灰度值比较,大于阈值则标记为 1,否则标记为 0。从右上角开始顺时针旋转,排列 8 个 0/1标记值,得到一个 8 位二进制数,就是窗口中心像素点的 LBP 值。
LBPP,R(xc,yc)=∑p=0P−1S(gp−gc)∗2pS(gp−gc)={1,gp≥gc0,gp<gcLBP_{P,R} (x_c,y_c) = \sum_{p=0}^{P-1} S(g_p-g_c)*2^p\\ S(g_p-g_c) = \begin{cases} 1, \quad g_p \ge g_c\\ 0, \quad g_p \lt g_c \end{cases} LBPP,R(xc,yc)=p=0P1S(gpgc)2pS(gpgc)={1,gpgc0,gp<gc

LBP 算子利用了邻域点的量化关系,可以有效地消除光照对图像的影响。只要光照变化不足以改变相邻像素点的像素值的大小关系,LBP 算子的值就不会发生变化。


例程 14.7:特征描述之 LBP 纹理特征算子

OpenCV 中实现了 LBP 特征的计算,但没有提供单独的 API。skimage 特征检测与提取对各种 LBP 的方法提供了丰富的封装函数。

本例程比较不同方法实现 LBP 的性能,同时考察 LBP 排列顺序的影响。

    #  14.7 特征描述之 LBP 纹理特征算子 (Local binary patterns)def getLBP1(gray):height, width = gray.shapedst = np.zeros((height, width), np.uint8)kernel = np.array([1, 2, 4, 128, 0, 8, 64, 32, 16]).reshape(3,3)  # 从左上角开始顺时针旋转# kernel = np.array([64,128,1,32,0,2,16,8,4]).reshape(3,3)  # 从右上角开始顺时针旋转for h in range(1, height-1):for w in range(1, width-1):LBPMat = (gray[h-1:h+2, w-1:w+2] >= gray[h, w])  # 阈值比较dst[h, w] = np.sum(LBPMat * kernel)  # 二维矩阵相乘return dstdef getLBP2(gray):height, width = gray.shapedst = np.zeros((height, width), np.uint8)# kernelFlatten = np.array([1, 2, 4, 128, 0, 8, 64, 32, 16])  # 从左上角开始顺时针旋转kernelFlatten = np.array([64,128,1,32,0,2,16,8,4])  # 从右上角开始顺时针旋转for h in range(1, height-1):for w in range(1, width-1):LBPFlatten = (gray[h-1:h+2, w-1:w+2] >= gray[h, w]).flatten()  # 展平为一维向量, (9,)dst[h, w] = np.vdot(LBPFlatten, kernelFlatten)  # 一维向量的内积return dstdef getLBP3(gray):height, width = gray.shapedst = np.zeros((height, width), np.uint8)for h in range(1, height-1):for w in range(1, width-1):center = gray[h, w]code = 0  # 从左上角开始顺时针旋转code |= (gray[h-1, w-1] >= center) << (np.uint8)(7)code |= (gray[h-1, w  ] >= center) << (np.uint8)(6)code |= (gray[h-1, w+1] >= center) << (np.uint8)(5)code |= (gray[h  , w+1] >= center) << (np.uint8)(4)code |= (gray[h+1, w+1] >= center) << (np.uint8)(3)code |= (gray[h+1, w  ] >= center) << (np.uint8)(2)code |= (gray[h+1, w-1] >= center) << (np.uint8)(1)code |= (gray[h  , w-1] >= center) << (np.uint8)(0)dst[h, w] = codereturn dst# 原始 LBP 算法:选取中心点周围的 8个像素点,阈值处理后标记为 8位二进制数img = cv2.imread("../images/fabric1.png", flags=1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度图像# 1) 二重循环, 二维矩阵相乘timeBegin = cv2.getTickCount()imgLBP1 = getLBP1(gray)  # # 从左上角开始顺时针旋转timeEnd = cv2.getTickCount()time = (timeEnd-timeBegin)/cv2.getTickFrequency()print("1) 二重循环, 二维矩阵相乘:", round(time, 4))# 2) 二重循环, 一维向量的内积timeBegin = cv2.getTickCount()imgLBP2 = getLBP2(gray)  # 从右上角开始顺时针旋转timeEnd = cv2.getTickCount()time = (timeEnd-timeBegin)/cv2.getTickFrequency()print("2) 二重循环, 一维向量的内积:", round(time, 4))# 3) 二重循环, 按位操作timeBegin = cv2.getTickCount()imgLBP3 = getLBP3(gray)  # 从右上角开始顺时针旋转timeEnd = cv2.getTickCount()time = (timeEnd-timeBegin)/cv2.getTickFrequency()print("3) 二重循环, 按位操作:", round(time, 4))# 4) skimage 特征检测from skimage.feature import local_binary_patterntimeBegin = cv2.getTickCount()lbpSKimage = local_binary_pattern(gray, 8, 1)timeEnd = cv2.getTickCount()time = (timeEnd-timeBegin)/cv2.getTickFrequency()print("4) skimage.feature 封装:", round(time, 4))plt.figure(figsize=(9, 6))plt.subplot(231), plt.axis('off'), plt.title("origin")plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.subplot(232), plt.axis('off'), plt.title("gray")plt.imshow(gray, 'gray')plt.subplot(233), plt.axis('off'), plt.title("LBP(skimage)")plt.imshow(lbpSKimage, 'gray')plt.subplot(234), plt.axis('off'), plt.title("LBP(TopLeft)")plt.imshow(imgLBP1, 'gray')plt.subplot(235), plt.axis('off'), plt.title("LBP(TopRight)")plt.imshow(imgLBP2, 'gray')plt.subplot(236), plt.axis('off'), plt.title("LBP(Bitwise)")plt.imshow(imgLBP3, 'gray')plt.tight_layout()plt.show()

运行结果:

  1. 二重循环, 二维矩阵相乘: 2.7288
  2. 二重循环, 一维向量的内积: 1.7105
  3. 二重循环, 按位操作: 8.3292
  4. skimage.feature 封装: 0.0756

运行结果表明,不同的程序实现方法,对于运算速度的影响很大。

而不同的 LBP 排列顺序(从左上角或右上角开始循环)对提取纹理特征的影响并不大。


在这里插入图片描述


【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125670942)
Copyright 2022 youcans, XUPT
Crated:2022-7-7

222. 特征提取之弗里曼链码
225. 特征提取之傅里叶描述子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php日志数据统计,awk 进行php日志累计报错统计

问题线上服务器一百多台通过tail -f /var/log/error_web* 方式来查看&#xff0c;速度滚动刷新太快&#xff0c;而且不方便定位问题按照前辈的『观察法』&#xff0c;作为新人实在是有难度&#xff0c;所以使用awk命令对输出格式格式化了一下。思路将每一行tail得到的日志通过a…

【OpenCV 例程200篇】228. 特征描述之 extendLBP 改进算子

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】228. 特征描述之 extendLBP 改进算子 特征通常是针对于图像中的某个目标而言的。针对目标所在区域的特征描述符&#xff08;Region descriptors&#xff09;&#xff0c;称为区域特征描述子。 局部…

Java设计模式汇总详解

设计模式 设计模式是很多程序员总结出来的最佳实践。曾经在刚开始写项目的时候学习过设计模式&#xff0c;在开发过程中&#xff0c;也主动或者被动的使用过。现在写代码虽说不会特意明确在用哪种设计模式&#xff0c;但潜移默化的写出来公认的最佳实践代码&#xff0c;毕竟看…

php中reset函数,PHP reset()函数

实例 1所有相关方法的演示&#xff1a;$people array("Peter", "Joe", "Glenn", "Cleveland");echo current($people) . ""; // The current element is Peterecho next($people) . ""; // The next element of …

【OpenCV 例程200篇】229. 特征描述之 LBP 算子比较(skimage)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】229. 特征描述之 LBP 算子比较&#xff08;skimage&#xff09; 局部二值模式&#xff08;LBP&#xff0c;Local binary patterns&#xff09;是一种用来描述图像局部纹理特征的算子&#xff0c;它具…

Java多线程的使用

无论在我们的工作中还是在我们的生活中&#xff0c;我们都会用到多线程的知识&#xff0c;今天就给大家讲一下如何使用多线程。 序幕 线程的启动 如何使线程暂停 如何使线程停止 线程的优先级 线程安全相关的问题 我们首先要知道进程和线程分别是什么&#xff1f; 进程 - 进…

oracle 存储过程 db,oracle数据库的存储过程是什么?

oracle数据库的存储过程&#xff1a;一组为了完成特定功能的SQL语句集&#xff0c;经编译后存储在数据库中。存储过程是由流控制和SQL语句书写的过程&#xff0c;这个过程经编译和优化后存储在数据库服务器中&#xff0c;应用程序使用时只要调用即可。存储过程(Stored Procedur…

【OpenCV 例程200篇】230. 特征描述之 LBP 统计直方图

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】230. 特征描述之 LBP 统计直方图 局部二值模式&#xff08;LBP&#xff0c;Local binary patterns&#xff09;是一种用来描述图像局部纹理特征的算子&#xff0c;它具有旋转不变性和灰度不变性的优点…

论单线程和多线程

在我们日常的项目开发过程中进场会接触到单线程或多线程的知识&#xff0c;那么到底多线程好还是单线程好呢&#xff1f;单线程和多线程的区别又是什么呢&#xff1f;下面我们来看看它们的区别以及优缺点分析及实例展示。 一、线程的含义 线程&#xff1a;每一个任务称为一个…

oracle 表空间初始分配,在 Oracle 中创建用户时,若未提及 DEFAULT TABLESPACE 关键字,则 Oracle 就将 ( )表空间分配给用户作为默认表空间。...

【多选题】现代职业高尔夫运动,主要有如下构成要素,即:高水平的职业球员、( )、观众的积极参与、( )和( )。【判断题】凝点较高的含蜡原油,凝点附近粘温曲线很陡,经济进站油温常略高于凝点。( )【单选题】以下哪项不是固有免疫的物理屏障作用【多选题】下列各项中不属于“木”的…

【OpenCV 例程200篇】232. 特征描述之频谱方法

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】232. 纹理特征之频谱方法 4.3 纹理特征之频谱方法 傅里叶谱可以描述图像中的周期性或半周期性二维模式的方向性&#xff0c;因此可以基于傅里叶变换对纹理进行频谱分析。 纹理与图像频谱中的高频分…

并发编程的目的和挑战

并发编程的目的与挑战 并发编程的目的是为了让程序运行得更快。启动更多的线程并不一定就能让程序最大限度地并发执行。 希望通过多线程执行任务让程序运行得更快&#xff0c;会面临非常多的挑战。比如&#xff1a; 上下文切换的问题死锁的问题硬件和软件的资源限制问题上下文…

java制作oracle程序,Java程序操作Oracle两种方式之简单实现

Java程序操作Oracle两种方式之简单实现1.通过JDBC-ODBC桥连接Oracle数据库(1)创建odbc源&#xff0c;在控制面板->管理工具->数据源(odbc)中添加DSN,比如取名为wangtao,选择一个Service,输入用户名密码&#xff0c;测试连接&#xff0c;若通过说明成功&#xff1b;(注意&…

【OpenCV 例程200篇】233. 区域特征之矩不变量

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】233. 区域特征之矩不变量 4.4 区域特征之矩不变量 矩是概率与统计中的一个概念&#xff0c;是随机变量的一种数字特征。矩函数在图像分析中有着广泛的应用&#xff0c;如模式识别、目标分类、图像编…

oracle ip策略,ip rule -- 路由策略数据库管理命令

ip rule -- 路由策略数据库管理命令.8.ip rule -- 路由策略数据库管理命令8.1.缩写rule、ru8.2.对象路由策略数据库的规则用于控制选择路由的算法。Internet上采用的路由算法一般是基于数据包目的地址的。理论上&#xff0c;也可以由TOS域决定&#xff0c;不过这没有实际应用。…

【OpenCV 例程200篇】231. 特征描述之灰度共生矩阵(GLCM)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】231. 特征描述之灰度共生矩阵&#xff08;GLCM&#xff09; 4.2.4 灰度共生矩阵&#xff08;GLCM&#xff09; 灰度共生矩阵&#xff08;Gray level co-occurrence matrix&#xff0c;GLCM&#xff…

oracle11 处理器数,11G AWR中%Total CPU与%Busy CPU指标的疑问

ODM FINDING:FROM http://www.os2ora.com/how-to-analyze-awr-report-1/ 推荐 kaya 的这篇文章引用如下&#xff1a;如果关注数据库的性能&#xff0c;那么当拿到一份AWR报告的时候&#xff0c;最想知道的第一件事情可能就是系统资源的利用情况了&#xff0c;而首当其冲的&am…

【OpenCV 例程200篇】237. 基于主成分提取的方向校正(OpenCV)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】237. 基于主成分提取的方向校正&#xff08;OpenCV&#xff09; 主成分分析&#xff08;Principal Components Analysis&#xff0c;PCA&#xff09;是一种基于统计的数据降维方法&#xff0c;又称主…

Java中12个原子操作类

Java 从 JDK 1.5 开始提供了 java.util.concurrent.atomic 包&#xff08;以下简称Atomic包&#xff09;&#xff0c;这个包中的 原子操作类 提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。 因为变量的类型有很多种&#xff0c;所以在 Atomic 包里一共提供了 …

swoole 捕捉php错误,swoole怎么处理错误

在协程编程中可直接使用try/catch处理异常。但必须在协程内捕获&#xff0c;不得跨协程捕获异常。不仅是应用层throw的Exception&#xff0c;底层的一些错误也是可以被捕获的&#xff0c;如function、class、method不存在下面的代码中&#xff0c;try/catch和throw在不同的协程…