算术编码(多媒体实验一)
sklearn主成分分析pca用python实现(多媒体实验二)
BOW图像检索corel数据集(多媒体实验三)
手写数字识别(多媒体实验五)
如果想用基于python的sklearn库参考
代码基本都是参考网上PCV版本的,基本都是调库,没有实现sift,k-mean等。仅供在python3.8版本,sqlite3中下复现。
本来想用opencv处理,但版本和依赖库问题加上个人能力不足没有造过sift等轮子就不多说。
参考:
- Bag of Features (BOF)图像检索算法及其python实现(附代码):网上基本都是一个版本,原谅我找不到原文的代码。
- Python计算机视觉——基于BOW的图像检索学习:我遇到的大部分错误他也遇到了,只不过他的有些修改方式还是不适合py3.8版本。
- 计算机视觉8—基于BOW模型的图像检索和匹配:一模一样的代码,只不过不用手动查看内置源函数了,比如万恶的imagesearch.py文件,这个版本用的pysqlite2和python3是冲突的,所以造成了很多问题。
原理不多讲,先看针对corel数据集的图像处理。
imlist获取文件的jpg的路径,然后featlist是PCV的sift生成sift的路径名。
imlist = get_imlist("./corel/0/")
for i in range(1,10):
tmpimlist = get_imlist("./corel/{}/".format(i))
imlist.extend(tmpimlist)
nbr_images = len(imlist)
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]
其他基本和网上其他代码流程一样。主要是PCV是python2版本时期的东西,所以会有很多报错。以下详细讲讲具体报错解决方法:
-
首先需要手动安装PCV和配置vlfeat。pcv无法用pip3下载,所以下载完手动安装到conda环境里。PCV参考:python中PCV库安装的方法步骤。配置vlfeat参考Sift算法的原理描述以及对比Harris算法的特征匹配结果。vlfeat下载版本为window那个,安装32位再下载64位补丁即可。下载地址:VLFeat.org
-
配完后先跑createsift.py,会生成sift文件和plk数据包。报错No module named 'pysqlite2’,这是因为imagesearch.py文件是python2时期的代码,所以我们进入这个内置函数文件,把头文件pysqlite2改为sqlite3即可。
-
生成sift文件以及pkl数据包后运行import.py文件,第一次运行不会报错,之后报错sqlite3.OperationalError: table imlist already exists,是因为程序在之前运行过一次已经生成了table imlist.注释掉这一行即可。
-
‘cmp’ is an invalid keyword argument for sort():这是因为python3不支持cmp函数了,讲cmp函数改为cmp_to_key()即可。然后导入
from functools import cmp_to_key
- 运行查询文件query.py会报错TypeError: a bytes-like object is required, not 'str’:因为python3和Python2在套接字返回值解码上有区别,我们不必改自己函数的imlist为str型,而是去改imagesearch的返回值,否则会在查询数据库时报错语法错误。在文件99行,即Searcher类的get_imhistogram函数返回return为str类型。
# use pickle to decode NumPy arrays from string
# return pickle.loads(str(s[0]))
return pickle.loads(bytes(s[0]))
- 如果想手动查看db文件,需要下载sqlite3的应用包,我们可以看见其中表名,命令.table即可,然后可以进行增删改查等操作来判断python中对数据库操作是否符合语法。sqlite下载参考:使用SQLite打开本地*.db文件。
vocabulary.py:帮助理解词组意思,以及调用k-mean的作用:
from numpy import *
from scipy.cluster.vq import *
from PCV.localdescriptors import sift
class Vocabulary(object):
def __init__(self, name):
self.name = name
self.voc = []
self.idf = []
self.trainingdata = []
self.nbr_words = 0
def train(self, featurefiles, k=100, subsampling=10):
""" 用含有k个单词的K-means列出在featurefiles中的特征文件训练出一个词汇。对训练数据下采样可以加快训练速度 """
nbr_images = len(featurefiles)
# 从文件中读取特征
descr = []
descr.append(sift.read_features_from_file(featurefiles[0])[1])
descriptors = descr[0] # 将所有的特征并在一起,以便后面进行K-means聚类
for i in arange(1, nbr_images):
descr.append(sift.read_features_from_file(featurefiles[i])[1])
descriptors = vstack((descriptors, descr[i]))
# k-means: 最后一个参数决定运行次数
self.voc, distortion = kmeans(descriptors[::subsampling, :], k, 1)
self.nbr_words = self.voc.shape[0]
# 遍历所有的训练图像,并投影到词汇上
imwords = zeros((nbr_images, self.nbr_words))
for i in range(nbr_images):
imwords[i] = self.project(descr[i])
nbr_occurences = sum((imwords > 0) * 1, axis=0)
self.idf = log((1.0 * nbr_images) / (1.0 * nbr_occurences + 1))
self.trainingdata = featurefiles
def project(self, descriptors):
""" 将描述子投影到词汇上,以创建单词直方图 """
# 图像单词直方图
imhist = zeros((self.nbr_words))
words, distance = vq(descriptors, self.voc)
for w in words:
imhist[w] += 1
return imhist
def get_words(self, descriptors):
""" Convert descriptors to words. """
return vq(descriptors, self.voc)[0]
源码及数据库corel集见Media_xdu/bof