BOF 计算机视觉 以图搜图 Python

Bag of Features算法

  • 题目
  • 一、BOF算法是什么?
  • 二、详细步骤
    • 1.基于SIFT算法提取图像的特征
    • 2.对特征集进行K-means聚类
    • 3.获得初始BOF向量
    • 4.计算TF-IDF,并获得最终BOF
    • 5.以图搜图
    • 6.展示结果
  • 三、结果

题目

BOF算法概念、步骤、注意事项

【实验要求】使用颜色直方图或者bof算法来提取图像特征,在指定数据集上实现以图搜图,即输入数据集中某一张图,在剩下的999张图里搜索最邻近的10张图。


一、BOF算法是什么?

BOF(Bag of Features)算法实际上就是BOW(Bag of Words)算法在图像领域的应用。
步骤如下:
1.对数据集中所有图像进行sift特征提取,每幅图像获得不定数量的128维特征。
2.对所有特征进行k-means聚类,生成词典。本质就是去重合并。最后聚类的类样本中心点就是一个个的词。所有的词构成词典。
3.用词典对每幅图像进行处理,生成每幅图像的初步BOF特征(本质是每幅图中所用词典中的词的统计频数),维度等于词典中词的个数。
4.计算词典中词的TF-IDF。再次对图像进行处理。获得每张图最终的BOF向量,也即每幅图对应的有序的词集。
5.随机输入一张数据集中的图像,输出其余999张图像中与之余弦相似度最大的10张图像

二、详细步骤

1.基于SIFT算法提取图像的特征

SIFT算法在cv2这个库中我们直接调用即可,安装方法如下:
cv2库安装
最后返回的des是特征向量的集合,类型是多维数组。

import cv2
import numpy as np# 读取图像
img = cv2.imread(pictName) # 图像路径
# 转化为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 构造sift函数
sift = cv2.SIFT_create()
# 找出关键点
kp = sift.detect(gray, None)
# 使用关键点找出sift特征向量
kp, des = sift.compute(gray, kp)return des  

2.对特征集进行K-means聚类

将对所有图像处理所得到的特征放在一起,进行K-means聚类。k均值聚类也可以调用sklearn库的KMeans方法,并且这个自带的聚类拥有多线程的隐操作,聚类结果出来特别快。之前手写了一个,聚一次比调库迭代300次还要慢10倍。。。。真的麻了。

from sklearn.cluster import KMeansdef Kmeans(pictsFeatsAll, wordsNum=150): # 数据集,类别数,默认150类estimator = KMeans(n_clusters=wordsNum, max_iter=300)  # 构造聚类器estimator.fit(pictsFeatsAll)  # 聚类# label_pred = estimator.labels_  # 获取聚类标签wordsDict = estimator.cluster_centers_return wordsDict # 视觉字典

最后只需要将所有的样本中心点返回就行了,样本中心点就是聚类出来的词。

3.获得初始BOF向量

这一步呢通过上一步获得的字典,去判断每张图的特征是属于什么词,获得一个与字典词数相同维度大小的词频数向量,这就是初始的BOF向量。

def preBOFPlus(wordsDict, allFeats2WordsIndex, featsNums):  # 写书# 词典(150*128),每个特征被划分到的簇(对应词在词典的下标,70w个int),每张图像的特征数(1000个数) ,70w是之前sift出来的特征数preIDF = [0 for i in range(len(wordsDict))]pictsPreBOF = []ddd = 0for i in featsNums:     # 1000个长度   #时间复杂度为o(featNums=70w)# 字典长度个0。表示一本书,一张图就是一本书,书里面有很多词,BOF就是用视觉词的“频率”表示一张图tempBOF = [0 for k in range(len(wordsDict))]tempIDF = set()# 1 分割获得每幅图的词 ,统计每幅图的词 形成频数向量for j in range(ddd, ddd+i):t = allFeats2WordsIndex[j]  # 获得一个词的序号tempBOF[t] += 1             # 写书,形成频数向量if t not in tempIDF:preIDF[t] += 1tempIDF.add(t)# 2 组合1000本书pictsPreBOF.append(tempBOF)ddd += i# 返回的是每张图的无权BOF,也就是(150*1)表示词的频数 pictsPreBOF= 1000*150# preIDF是每个词属不属于这张图,里面有它就加1,没有就加0  从属关系 150*1return preIDF, pictsPreBOF

返回的preIDF是 对于词典中的每个词,统计它在多少张图中出现过。

4.计算TF-IDF,并获得最终BOF

什么是TF-IDF?

  # 4.计算词典中词的TF-IDF。再次对图像进行处理。得到每幅图像的最终的有权BOF# 计算IDFIDF = preIDFfor i in range(len(IDF)):if IDF[i] == 0:  # 说明 有的词 《消失了》print(f"preIDF的第{i}维为0,程序异常!结束")exit()IDF[i] = 1000.0 / float(IDF[i])# 计算有权BOFpictsBOF = copy.deepcopy(pictsPreBOF)for i in range(len(pictsBOF)):  # 1000lenFeatsNum = float(featsNums[i])for j in range(wordsNum):pictsBOF[i][j] = float(pictsBOF[i][j]**2) * IDF[j] / lenFeatsNum# 根据需要获得TF-IDF矩阵# TF_IDF = pictsPreBOF# for i in range(len(pictsBOF)):  # 1000#     for j in range(wordsNum):#       TF_IDF[i][j] = pictsBOF[i][j]/float(TF_IDF[i][j])

5.以图搜图

随机输入一张图,返回最接近的10张图的标号。

def onePicFindMore(picNum, pictsBOF, simlPicsNum=10):  # 默认取10# 获得输入图像的BOF向量inputPicBOF = pictsBOF[picNum]# 计算它与其他图像的余弦相似度picsSimil = []  # 相似度for i in range(len(pictsBOF)):picsSimil.append([cosineSimiliar(inputPicBOF, pictsBOF[i]), i])  # 加入标号picsSimil.sort(reverse=True)            # 按照相似度从大到小排序picsSimil.pop(0)                        # 除掉第一个,第一个一定是自己picsSimil = picsSimil[:simlPicsNum]     # 保留指定数量的图像标号picsNumber = []                         # 返回的标号for i in range(len(picsSimil)):picsNumber.append(picsSimil[i][1])  # 第二个数是标号return picsNumberdef cosineSimiliar(a, b):am = 0.0bm = 0.0aMutib = 0.0for i in range(len(a)):am += a[i]**2bm += b[i]**2aMutib += a[i]*b[i]return aMutib/math.sqrt(am*bm)

6.展示结果

仅用数字下标其实也能看出来是不是同类,但是不知道为啥不是同类。如果将结果图像放在一起,能更清楚的观察到图像间的相似和差异,以及为什么不是一类的图像确是很相似的。

    def displayPics(PicsNumber):    # 输入图像标号picsNames = []  # 图像的路径以及名称picsArray = []  # 图像listfor i in PicsNumber:PicsNames = f'corel/{int(i/100)}/{i}.jpg'  # 文件路径picsNames.append(f'{i}.jpg')# 读取文件 : opencv的颜色通道顺序为[B,G,R],而matplotlib颜色通道顺序为[R,G,B],所以需要调换一下通道位置picsArray.append(cv2.imread(PicsNames)[:, :, (2, 1, 0)])  # 调换通道temp = picsNames.pop()picsNames.append('INPUT : '+temp)for i in range(len(PicsNumber)):plt.subplot(3, 5, i+1)plt.imshow(picsArray[i], 'gray')plt.title(picsNames[i])plt.xticks([])plt.yticks([])plt.show()return

三、结果




可以看到,
第一幅图背景简单,恐龙图里都只有恐龙一个物体,检测到的特征点比较少,查找相似精度高,那张大象呢,也很明显,简单的背景和单一物体成像,相似度确实高。
第二幅图是花类的图像。能找一个恐龙出来我是没想到的,估计是对比度的问题,花类图片就是花瓣的部分亮度比较高,到了边缘就有一个亮度的突变,很快就变黑,恐龙的边缘也差不多。然后就造成了这个结果。
第三幅图是草地和马,这个特征就太明显了,草地和马都有自己很鲜明的特征,这个精度高是很正常的
第四幅图是车类。这种车的轮廓决定了它的特征很好找。最后结果还是不错的。
整体准确度还是比较高的。当然也有一部分近似度很低的,就不放图了。
这是一次有趣的实验。

BOF算法 基于SIFT+KMeans相关推荐

  1. lda进行图片分类_基于SIFT+Kmeans+LDA的图片分类器的实现

    题记:2012年4月1日回到家,南大计算机研究僧复试以后,等待着的就是独坐家中无聊的潇洒.不知哪日,无意中和未来的同学潘潘聊到了图像处理,聊到了她的论文<基于LDA的行人检测>,出于有一年 ...

  2. 基于SIFT+Kmeans+LDA的图片分类器的实现

    转自: http://blog.csdn.net/zhuzhutingru1/article/details/8217099 features opencv 词袋 sift LDA 目录(?)[-] ...

  3. 基于SIFT+Kmeans+SVM的场景识别,参数需注意的问题(Matlab实现)

    具体细节请参考我的论文 http://download.csdn.net/detail/m0_37393277/9895391 1.试验目的: 实现20类的建筑图片分类. 2.实现方法及正确率: 可参 ...

  4. 聚类优化算法——基于Kmeans算法

    聚类优化算法--基于Kmeans算法 Kmeans算法 Kmeans算法的基本原理及计算流程见上文--Kmeans算法及简单案例 Kmeans算法的优缺点 优点 - 原理简单(靠近中心点),实现容易 ...

  5. 基于sift特征提取的图像配准算法matlab仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 SIFT 是一种从图像中提取独特不变特征的方法,其特点为基于图像的一些局部特征,而与图像整体的大小和 ...

  6. m基于sift特征提取和模板匹配的车标识别算法matlab仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 车标识别技术研究是近几年出现的,尚未成熟.智能交通系统主要应用于高速公路收费管理系统.高速公路超速自 ...

  7. 【机器学习基础】数学推导+纯Python实现机器学习算法23:kmeans聚类

    Python机器学习算法实现 Author:louwill Machine Learning Lab 聚类分析(Cluster Analysis)是一类经典的无监督学习算法.在给定样本的情况下,聚类分 ...

  8. matlab人民币识别,Matlab图像处理学习笔记(六):基于sift特征点的人民币识别...

    本文记录如何利用sift特征点进行人民币的识别.本文给出的matlab源码识别了1元与100元人民币的面额,相同思路,可以对各种币值的人民币进行面额.正反面的识别.但由于本程序采用串行,模板数的增多会 ...

  9. matlab中k-means算法_机器学习 | KMeans聚类分析详解

    大量数据中具有"相似"特征的数据点或样本划分为一个类别.聚类分析提供了样本集在非监督模式下的类别划分.聚类的基本思想是"物以类聚.人以群分",将大量数据集中相似 ...

  10. opencv 基于sift的多张图片全景图拼接

    这里是基于sift来寻找特征点经行图像的匹配的原理来进行图像拼接的,具体步骤如下: 1.利用sift特征探测器来检测出两幅图片的sift特征点 2.根据上一步提取到的特征点来提取特征向量,使用Sift ...

最新文章

  1. Java程序内存分析:使用mat工具分析内存占用
  2. 你知道我们在等你吗?
  3. 纽约大街上的免费WiFi,终于铺起来了
  4. java 程序输出 赵_编写一个完整的JAVA的程序
  5. 《设计模式之禅》--空对象模式
  6. SQL Server安全机制–如何控制用户能够在报告中查看哪些数据
  7. [Angularjs]视图和路由(四)
  8. 3.4.2 - Operators 3.4.3 division and truncation
  9. Android Studio中导入第三方库
  10. fanuc系统md和mf区别_fanuc mf系统小技巧汇总
  11. Java中什么是句柄
  12. 电机计算机仿真,电机调速系统的计算机仿真
  13. windows图标文件夹_如何在Windows 10中获取Windows 7的旧文件夹图标
  14. 英语3500词(四)workplace主题 (2022.1.16)
  15. 【06月24日】预分红股息率最高排名
  16. cocos2d-js的(layer)生命周期,ctor,onEnter,onExit的使用
  17. 大小口圆锥台计算机,2011年对口单招计算机试卷A04(18页)-原创力文档
  18. ArcGIS栅格数据四参数七参数投影变换
  19. 他是阿里P11,靠写代码写成合伙人,身家几十亿,没有他,我们可能刷不了淘宝!...
  20. 零基础学习深度学习_深度学习的基础!!!

热门文章

  1. 【GDOI2014模拟】雨天的尾巴
  2. 解决Maven Not Authorized问题
  3. HTML5 第004篇 <abbr>标签【定义缩写】
  4. win10只有c盘怎么分区_win10系统硬盘怎么分区
  5. CVPR 2019 Oral 论文解读 | 百度提出关于网络压缩和加速的新剪枝算法
  6. Grown Up Digital: How the Net Generation is Changing Your World
  7. 小新700换主板_算不算诚意之作?——联想小新700笔记本到手拆升级+换系统
  8. 【第一组】第五次冲刺例会纪要
  9. 北京开通企业登记“e窗通”服务平台 开办企业可3天完成
  10. 【干货】PS超实用功能:美化照片