基于纹理特征的kmeas聚类的图像分割方案

Gabor滤波器简介

在图像处理中,以Dennis Gabor命名的Gabor滤波器是一种用于纹理分析的线性滤波器,本质上是指在分析点或分析区域周围的局部区域内,分析图像中是否存在特定方向的特定频率内容。Gabor滤波器的频率和方向表示被许多当代视觉科学家认为与人类视觉系统的频率和方向表示相似。它们被发现特别适合于纹理表征和辨别。

在空间域,二维Gabor滤波器是由正弦平面波调制的高斯核函数(见Gabor变换)。

定义

由于Gabor滤波器脉冲响应的乘法卷积性质(卷积定理),其傅里叶变换等于谐波函数(正弦函数)的傅里叶变换与高斯函数的傅里叶变换的卷积。滤波器有一个实分量和一个虚分量表示正交方向。这两个分量可以组成一个复数,也可以单独使用。

图像特征提取

一组不同频率和方向的Gabor滤波器可能有助于从图像中提取有用的特征。在离散域中,二维Gabor滤波器:

其中BC是待确定的归一化因子。
二维Gabor滤波器在图像处理中有着丰富的应用,特别是在纹理分析和分割的特征提取方面。f定义了在纹理中寻找的频率。通过改变theta,我们可以寻找面向特定方向的纹理。通过改变sigma,我们改变了支持或被分析图像区域的大小。

2-D Gabor滤波器在图像处理的应用

在图像处理中,Gabor特征是识别的理想选择。在文档图像处理中,Gabor特征是识别多语言文档中单词的脚本的理想选择由于文本具有丰富的高频成分,而图片本质上相对平滑,不同频率和不同方向的Gabor滤波器已被用于从复杂文档图像(包括灰色和彩色)中定位和提取纯文本区域。它还被应用于面部表情识别。Gabor滤波器在模式分析中也得到了广泛的应用。例如,它已被用于研究脊柱多孔海绵状小梁内的指向性分布。Gabor空间在光学字符识别、虹膜识别和指纹识别等图像处理应用中非常有用。特定空间位置的激活之间的关系在图像中的物体之间非常不同。此外,重要的激活可以从Gabor空间中提取,以创建一个稀疏的对象表示。

Gabor在python中的实现

1.	#构建Gabor滤波器  
2.	def build_filters(num_orientations=8):  
3.	    filters = []  
4.	    # 定义多个不同方向的Gabor滤波器参数  
5.	    ksize = [7, 9, 11, 13, 15, 17]  # 滤波器的大小  
6.	    sigma = 4.0  # 高斯函数的标准差  
7.	    lambd = 10.0  # 波长  
8.	    gamma = 0.5  # 高斯核的椭圆度  
9.	    # num_orientations = 8  # 设定多个不同方向的Gabor滤波器  
10.	  
11.	    for theta in np.linspace(0, np.pi, num_orientations, endpoint=False):  
12.	        for k in ksize:  
13.	            gabor_filter = cv2.getGaborKernel((k, k), sigma, theta, lambd, gamma, ktype=cv2.CV_32F)  
14.	            filters.append(gabor_filter)  
15.	  
16.	    #绘制滤波器  
17.	    plt.figure(1)  
18.	    for temp in range(len(filters)):  
19.	        plt.subplot(8, 6, temp + 1)  
20.	        plt.imshow(filters[temp])  
21.	    plt.show()  
22.	  
23.	    return filters  

上述代码构建了6个不同尺度下,8个不同方向上,共48个滤波核构成的的Gabor滤波器组,如下图所示

分别使用这48个滤波器组对图像(灰度)进行特征提取,并拼接成特征矩阵,代码如下: 

1.	#Gabor特征提取  
2.	def getGabor(img, filters):  
3.	    features_list = [] #滤波结果  
4.	    for filter in filters:  
5.	        # 对图像应用多个不同尺度不同方向的Gabor滤波器,并将特征合并为一个特征向量  
6.	        filtered_image = cv2.filter2D(img, cv2.CV_8UC1, filter)  
7.	        features = filtered_image.reshape(-1)  
8.	        features_list.append(features)  
9.	  
10.	    feature_matrix = np.array(features_list).T  
11.	    return feature_matrix  

该特征矩阵的维度为(H×W,48),即每个像素都有一个48维的特征向量,通过使用kmeans聚类算法计算这些特征向量的相似度,对每个像素进行4分类

1.	def kmeansSeg(feature_matrix, num_clusters):  
2.	    # 使用Kmeans进行聚类  
3.	    kmeans = KMeans(n_clusters=num_clusters, random_state=0)  
4.	    kmeans.fit(feature_matrix)  
5.	    # 获取聚类结果  
6.	    labels = kmeans.labels_  
7.	    return labels  

对得到的标签进行颜色映射,输出结果如下

可以看到,当聚类簇数为4时的分割效果是较好的,注意我们在gabor滤波器中只调整了不同的方向和尺度特征,因此得到的聚类效果也是对不同方向下的聚类效果

接下来我们来看在不同聚类簇数下的聚类效果

 可以看到,在不同聚类簇数下对纹理特征的聚类效果各不相同,其中当聚类簇数为4时效果较好

完整源码 

import cv2
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeansclass GaborSegmention():def __init__(self,img,num_orientations = 8):#初始化滤波器self.img=imgself.filters = []# 定义6个不同尺度和num_orientations个不同方向的Gabor滤波器参数ksize = [7, 9, 11, 13, 15, 17]  # 滤波器的大小sigma = 4.0  # 高斯函数的标准差lambd = 10.0  # 波长gamma = 0.5  # 高斯核的椭圆度# num_orientations = 8  # 设定多个不同方向的Gabor滤波器for theta in np.linspace(0, np.pi, num_orientations, endpoint=False):for k in ksize:gabor_filter = cv2.getGaborKernel((k, k), sigma, theta, lambd, gamma, ktype=cv2.CV_32F)self.filters.append(gabor_filter)# 绘制滤波器plt.figure(figsize=(12, 12))for i in range(len(self.filters)):plt.subplot(8, 6, i + 1)plt.imshow(self.filters[i])plt.axis('off')plt.show()def getGabor(self):feature_matrix=[]for filter in self.filters:# 对图像应用6个不同尺度8个不同方向的Gabor滤波器,得到一个h*w特征图filtered_image = cv2.filter2D(self.img, cv2.CV_8UC1, filter)# 一个特征图就表示某一个尺度下的某一个方向下的特征features = filtered_image.reshape(-1)feature_matrix.append(features)# 该结果表示每个像素的6个尺度8个方向Gabor特征向量feature_matrix = np.array(feature_matrix).Treturn feature_matrixdef kmeansSeg(self,num_clusters,feature_matrix):# 使用Kmeans进行聚类,即计算每个像素的特征向量(48个特征)的相似度kmeans = KMeans(n_clusters=num_clusters, random_state=0)kmeans.fit(feature_matrix)# 获取聚类结果labels = kmeans.labels_return labelsdef colorMap(self, labels):# 进行像素映射color_map = np.array([[255, 0, 0],  # 蓝色[0, 0, 255],  # 红色[0, 255, 0],  # 绿色[255, 255, 0],[0, 255, 255],[128, 128, 128]])# 将聚类结果转化为图像segmented_image = color_map[labels].reshape(self.img.shape[0], self.img.shape[1], 3).astype(np.uint8)return segmented_imageif __name__=="__main__":# 加载图像# image_path = r"./data/planets.jpg"image_path = r"./data/coins.jpg"img = cv2.imread(image_path)image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# print(image.shape)# 创建gaborSeg分割对象,初始化gabor滤波器gaborSeg=GaborSegmention(image)# 获取特征矩阵feature_matrix = gaborSeg.getGabor()# # 分割结果# labels=gaborSeg.kmeansSeg(num_clusters=4,feature_matrix=feature_matrix)# segmented_image=gaborSeg.colorMap(labels)num_clusters=[2,4,6]seglabels=[ gaborSeg.kmeansSeg(num_clusters=num_cluster,feature_matrix=feature_matrix)for num_cluster in num_clusters]segmented_images=[gaborSeg.colorMap(labels) for labels in seglabels]# 显示结果plt.figure(figsize=(16, 8))# 原图plt.subplot(221)plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.axis('off')# 分割图for i,segmented_image in enumerate(segmented_images):plt.subplot(2,2,i+2)plt.imshow(segmented_image)plt.title("num_clusters={}".format(num_clusters[i]))plt.axis('off')# plt.subplots_adjust(hspace=0.2)plt.show()

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

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

相关文章

二十一、数组(3)

本章概要 Arrays的setAll方法增量生成 Arrays的setAll方法 在Java 8中, 在RaggedArray.java 中引入并在 ArrayOfGenerics.java.Array.setAll() 中重用。它使用一个生成器并生成不同的值,可以选择基于数组的索引元素(通过访问当前索引&…

Android项目更新依赖和打包步骤和问题汇总

目录 1、Android 项目打包,32位包升级到64位包问题一:ERROR: Conflicting configuration : armeabi-v7a,x86-64,arm64-v8a,x86 in ndk abiFilters cannot be present when splits abi filters are set : x86,armeabi-v7a,arm64-v8a 2、Android项目依赖升…

pytest-base-url插件之配置可选的项目系统URL

前言 ①当我们的自动化代码完成之后,通常期望可以在不同的环境进行测试,此时可以将项目系统的URL单独拿出来,并且可以通过pytest.ini配置文件和支持pytest命令行方式执行。 ② pytest-base-url 是一个简单的pytest插件,它通过命…

【数据结构】HashMap 和 HashSet

目录 1.哈希表概念 2冲突 2.1概念 2.2 冲突-避免 2.3冲突-避免-哈希函数设计 2.4 冲突-避免-负载因子调节 ​编辑 2.5 冲突-解决-开散列/哈希桶 2.5冲突严重时的解决办法 3.实现 4.性能分析 5.与Java集合类的关系 1.哈希表概念 在顺序结构中,元素关键码和存…

【vue+eltable】修改表格滚动条样式

<style lang"scss" scoped> ::v-deep .el-table__body-wrapper::-webkit-scrollbar {width: 10px; /*纵向滚动条的宽度*/height: 10px; /*横向滚动条的高度*/ } /*定义滚动条轨道 内阴影圆角*/ ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {bo…

Java 多线程之 volatile(可见性/重排序)

文章目录 一、概述二、使用方法三、测试程序3.1 验证可见性的示例3.2 验证指令重排序的示例 一、概述 在Java中&#xff0c;volatile 关键字用于修饰变量&#xff0c;其作用是确保多个线程之间对该变量的可见性和禁止指令重排序优化。 当一个变量被声明为volatile时&#xff0…

高德地图点击搜索触发输入提示

减少调用次数&#xff0c;不用每输入一次调用一次&#xff0c;输入完后再触发搜索 效果图&#xff1a; ![Alt](https://img-home.csdnimg.cn/images/20220524100510.png dom结构 <div class"seach"><van-searchshow-actionv-model"addressVal"…

【使用vscode在线web搭建开发环境--code-server搭建】

官方版本下载 https://github.com/coder/code-server/releases?q4.0.0&expandedtrue使用大于版本3.8.0,因为旧版本有插件市场不能访问的情况版本太高需要更新环境依赖 拉取安装包 []# wget "https://github.com/coder/code-server/releases/download/v4.0.0/code-…

探访九牧绿色黑灯工厂,找寻“科技卫浴 世界九牧”的答案

文 | 螳螂观察 作者 | 余一 你所想象中的工厂是怎么样的&#xff1f;灯火通明、人声鼎沸、人来人往&#xff1f;如果告诉你一座工厂既没有灯&#xff0c;也没有人&#xff0c;但却还在持续生产&#xff0c;你会不会觉得这是不可思议的事&#xff1f; 如果不是亲眼见证&#…

Simulink 自动代码生成:手写代码替换生成代码Code Replacement Tool使用

目录 前言 代码替换库操作步骤 代码生成验证 总结 前言 在实际工程开发过程中&#xff0c;Simulink生成的代码都是构建的算法实现的&#xff0c;纯软件实现&#xff0c;生成的代码大多也是直接在CPU上运行的。实际还有一些MCU集成了像Cordic&#xff0c;协处理器等。有些代…

WinEdt 11.1编辑器的尝鲜体验

WinEdt 11.1编辑器的尝鲜体验 2023年5月19日&#xff0c;WinEdt 11.1版本发布了&#xff0c;相比WinEdt 10.3, 最新版更加漂亮&#xff0c;更加友好&#xff0c;更加好用了&#xff01; 最大的改变是WinEdt 11.1 有了自带的WinEdtPDF阅读器&#xff0c;所以不再需要下载第三方…

ros2工作空间

我们先不管ros2工作空间是什么样子的&#xff0c;如果是我自己来搞一个工作空间&#xff0c;我一定是这样安排 一个文件夹用来放自己存放的文件&#xff0c;。。。。。。。。。。对应src文件夹 一个文件夹用来放编译后的文件&#xff0c;。。。。。。。。。。。对应intall文件…

2024测试工程师必学的Jmeter:利用jmeter插件收集性能测试结果汇总报告和聚合报告

利用jmeter插件收集性能测试结果 汇总报告&#xff08;Summary Report &#xff09; 用来收集性能测试过程中的请求以及事务各项指标。通过监听器--汇总报告 可以添加该元件。界面如下图所示 汇总报告界面介绍&#xff1a; 所有数据写入一个文件&#xff1a;保存测试结果到本地…

ZYNQ_project:LCD

模块框图&#xff1a; 时序图&#xff1a; 代码&#xff1a; /* // 24h000000 4324 9Mhz 480*272 // 24h800000 7084 33Mhz 800*480 // 24h008080 7016 50Mhz 1024*600 // 24h000080 4384 33Mhz 800*480 // 24h800080 1018 70Mhz 1280*800 */ module rd_id(i…

解决java在idea运行正常,但是打成jar包后中文乱码问题

目录 比如&#xff1a; 打包命令使用utf-8编码&#xff1a; 1.当在idea中编写的程序,运行一切正常.但是当被打成jar包时,执行的程序会中文乱码.产生问题的原因和解决方案是什么呢? 一.问题分析 分别使用idea和jar包形式打印出System中所有的jvm参数---代码如下: public static…

【设计模式】行为型设计模式

行为型设计模式 文章目录 行为型设计模式一、概述二、责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;三、命令模式&#xff08;Command Pattern&#xff09;四、解释器模式&#xff08;Interpreter Pattern&#xff09;五、迭代器模式&#xff08;Iterato…

Stable Diffusion专场公开课

从SD原理、本地部署到其二次开发 分享时间&#xff1a;11月25日14&#xff1a;00-17&#xff1a;00 分享大纲 从扩散模型DDPM起步理解SD背后原理 SD的本地部署:在自己电脑上快速搭建、快速出图如何基于SD快速做二次开发(以七月的AIGC模特生成系统为例) 分享人简介 July&#…

HelpLook VS Zendesk:哪种知识库软件更适合您的业务

为任何组织创造一个开放且协作的环境至关重要。然而&#xff0c;高水平的员工每周可能会花费多达30个小时处理电子邮件和协作&#xff0c;对他们的工作效率产生了重大影响。 为了解决这个挑战&#xff0c;建立一种高效的信息共享方法至关重要&#xff0c;不会妨碍团队的生产力…

福州大学《嵌入式系统综合设计》实验三:多媒体开发基础编程

一、实验目的 本实验基于搭建好的开发环境和硬件环境&#xff0c;通过编写简单的通信实验&#xff0c;验证开发环境&#xff0c;掌握多媒体开发编程基础&#xff0c;包括SOCKET编程、多线程编程和线程同步知识。 二、实验内容 基于套接字、多线程、同步锁机制实现多媒体文件…

循环链表3

插入函数——插入数据&#xff0c;在链表plsit的pos位置插入val数据元素 位置pos&#xff08;在无特别说明的情况下&#xff09;是从0开始计数的 要改变链表结构&#xff0c;就要依赖前驱&#xff0c;每个前驱的next存储着下一个数据结点的地址&#xff0c;也就是依靠前驱的ne…