目录

1.图像搜索

1.1 基于文本的图像检索

1.2 基于内容的图像检索(CBIR )

2.BOW模型图像检索流程

2.1 BOW(Bag-of-words)

2.2 Bag-of-features

2.3 TF-IDF(词频-逆向文档频率)

2.3 视觉单词

3.实验内容

3.1 数据集

3.2 实验流程及代码

4 总结


1.图像搜索

图像搜索,是通过搜索图像文本或视觉特征,为用户提供互联网上相关图形图像资料检索服务的专业搜索引擎系统,是搜索引擎的一种细分。一种是通过输入与图片名称或内容相似的关键字来进行检索,另一种通过上传与搜索结果相似的图片或图片URL进行搜索。

由于图像不同于文本,需要人们按照各自的理解来说明其蕴含的意义,需要人工干预找出图像并进行分类,因此图像检索比起文本的查询和匹配要困难得多。图像搜索引擎大多支持关键词检索和分类浏览两种检索方式,主要的检索途径有三种:①基于图像外部信息,即根据图像的文件名或目录名、路径名、链路、ALT标签以及图像周围的文本信息等外部信息进行检索;②基于图像内容特征描述,即人工对图像的内容(如物体、背景、构成、颜色特征等)进行描述并分类,给出描述词,检索时主要在这些描述词中搜索检索词;③基于图像形式特征的抽取,由图像分析软件自动抽取图像的颜色、形状、纹理等特征,建立特征索引库,只需将要查找的图像的大致特征描述出来,就可以找出与之具有相近特征的图像。

1.1 基于文本的图像检索

基于文本的图像检索沿用了传统文本检索技术,主要是利用文本标注的方式为图像添加关键词,比如图像的物体,场景等,从图像名称、图像尺寸、压缩类型、作者、知年代等方面标引图像,一般以关键词形式的提问查询图像,通过图片的名称、文字信息和索引关系来实现查询功能。

在检索图像时候直接根据所要搜索的关键词就可以检索到想要的图像,这种方式实现起来简单,但是非常耗费人工(需要人为给每一张图像标注),对于大型数据库检索不太现实。而且人工标注存在人为认知误差,对相同图像,人理解不一样,也到导致标注不一致,这是基于文本图像检索的一个缺点。

1.2 基于内容的图像检索(CBIR )

基于内容技术的图像检索系统,在建立图像数据库时, 系统对输入的图像进行分析并分类统一建模, 然后根据各种图像模型提取图像特征存入特征库, 同时对特征库建立索引以提高查找效率。系统采用相似性匹配算法计算关键图像特征与特征库中图像特征的相似度, 然后按照相似度从大到小的顺序将匹配图像反馈给用户。

使用了图像的可视特征对图像进行检索,本质上讲是一种近似匹配技术,融合了计算机视觉、图像处理、图像理解和数据库等多个领域的技术成果,其中的特征提取和索引的建立可由计算机自动完成,避免了人工描述的主观性。用户检索的过程一般是提供一个样例图像,系统抽取该查询图像的特征,然后与数据库中的特征进行比较,并将与查询特征相似的图像返回给用户。

2.BOW模型图像检索流程

2.1 BOW(Bag-of-words)

Bag-of-words 简称BOW,也叫做“词袋”,最初是为解决文档建模问题而提出的,在信息检索中,BOW模型假定对于一个文本,忽略其词序和语法、句法,将其仅看做是一个词集合,或者说是词的一个组合,文本中每个词的出现都是独立的,不依赖于其他词是否出现。

通过单词计数构建词袋,将文档转化为各个单词元素作为横坐标,以单词出现的次数作为纵坐标的直方图,从而建立文档索引,然后进行归一化处理,将每个词出现的频数作为文档的特征。

由于每篇文档长度不同,故除以直方图总和将向量归一化成单位长度。对于直方图向量中的每个元素,一般根据每个单词的重要性来赋予相应的权重。通常,数据集中一个单词的重要性与它在文档中出现的次数成正比,而与它在数据集中出现的次数成反比。最常用的权重TF-IDF(词频-逆向文档频率)。

基本流程:

  1. 构建图像库,即数据集
  2. 提取图像库中所有图像的局部特征,如SIFT
  3. 对特征集合进行聚类,聚类的中心对应特征形成的码字表示视觉词汇,视觉词汇的集合构成视觉词典,对应一个码书,即码字的集合
  4. 统计图像中各个视觉词汇出现的频率

2.2 Bag-of-features

将BoW引入到计算机视觉中,将一幅图像看成文本对象,图像中的不同特征可以看着构成图像的不同词汇,类似于文本的BoW模型,将图片分成若干个图像块,构建“词库”,就可以使用图像特征在图像中出现的频率,使用一个一维的向量来描述图像,这就是Bag-of-features

算法流程:

  1. 提取图像特征(常用SIFT)
  2. 训练字典,通过聚类算法对这些特征向量进行聚类(常用k-means),得到一部字典
  3. 量化图像特征,根据字典将图片表示成向量(直方图);
  4. 训练分类器,根据数据库图片的向量以及图片的标签,训练分类器模型
  5. 再提取图像特征,根据字典量化直方图向量,用分类器模型对直方图向量进行分类

2.3 TF-IDF(词频-逆向文档频率)

  • TF:词频(Term Frequency),指的是一个给定的词语在该文件中出现的次数。如果某个关键词在一篇文章中出现的频率高,则说明该词能表征文章的内容,该关键词在其它文章中很少出现,则认为此词语具有很好的类别区分度,对分类有很大的贡献。
  • IDF:逆文档频率(Inverse Document Frequency),描述了某一个特定词语的普遍重要性,如果文件数据库中包含词语A的文件越少,则IDF越大,则说明词语A具有很好的类别区分能力。

TF-IDF权值为词频与逆文档频率的乘积。

TF-IDF是用于信息检索的一种常用加权技术,在文本检索中用来评估词语对于一个文件数据库中的其中一份文件的重要程度。词语的重要性随着它在文件中出现的频率成正比增加,随着它在文件数据库中出现的频率成反比下降。

2.3 视觉单词

视觉单词,又叫视觉词典,正如上面Bag-of-features的介绍所说,为了将文本挖掘技术应用到图像中,首先需要建立视觉等效单词,可以通过SIFT局部描述子做到。

其主要思想是将描述子空间量化成一些典型实例,并将图像中的每一个描述子指派到其中的某个实例中。这些典型实例可以通过分析训练图像集确定,并被视为视觉单词,所有这些视觉单词构成的集合称为视觉词汇,也称为视觉码本,视觉词汇的集合构成视觉词典,对应一个码书,即码字的集合。对于给定的问题、图像类型,或在通常情况下仅需呈现视觉内容,可以创建特定的词汇。

即:视觉单词(码字)—(构成)—视觉词汇(视觉码本)—(构成)—视觉词典(码书)

3.实验内容

3.1 数据集

该数据集一共有150张图像,涉及建筑、动物、花卉等一共10个种类图片,每个种类图片15张。

3.2 实验流程及代码

3.2.1 对数据集做SIFT特征提取,采用K-means算法学习视觉词典

(1)vocabulary.py

from numpy import *
from scipy.cluster.vq import *from PCV.localdescriptors import siftclass Vocabulary(object):def __init__(self,name):self.name = nameself.voc = []self.idf = []self.trainingdata = []self.nbr_words = 0def 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 = featurefilesdef project(self,descriptors):""" 将描述子投影到词汇上,以创建单词直方图 """# 图像单词直方图 imhist = zeros((self.nbr_words))words,distance = vq(descriptors,self.voc)for w in words:imhist[w] += 1return imhistdef get_words(self,descriptors):""" Convert descriptors to words. """return vq(descriptors,self.voc)[0]

该代码创建一个词汇类,以及在训练图像数据集上训练出一个词汇的方法。vocabulary类包含了一个由单词聚类中心VOC与每个单词对应的逆向文档频率构成的向量,为了在某些图像集上训练词汇,train( )方法获取包含有.shift描后缀的述子文件列表和词汇单词数k。

(2)创建词汇

# -*- coding: utf-8 -*-
import pickle
from PCV.imagesearch import vocabulary
from PCV.tools.imtools import get_imlist
from PCV.localdescriptors import sift
from pylab import *
from PIL import Image# 获取图像列表
imlist = get_imlist('pic150/')
nbr_images = len(imlist)
# 获取特征列表
featlist = [ imlist[i][:-3] +'sift' for i in range(nbr_images)]# 提取文件夹下图像的sift特征
for i in range(nbr_images):im = array(Image.open(imlist[i]).convert('L'))sift.process_image(imlist[i], featlist[i])# 生成词汇
voc = vocabulary.Vocabulary('imagetest')
voc.train(featlist, 200, 10)
# 保存词汇
with open('vocabulary.pkl', 'wb') as f:pickle.dump(voc, f)
print ('vocabulary is:', voc.name, voc.nbr_words)

运行结果:

sift特征匹配为每个图像得到一个相应的.sift文件,生成vocabulary.pkl,用pickle模块保存了整个词汇对象。

3.2.2 创建图像索引,建立数据库

对图像进行索引,就是从这些图像中提取描述子,利用词汇将描述子转换成视觉单词,并保存视觉单词及对应图像的单词直方图。从而可以利用图像对数据库进行查询,并返回相似的图像作为搜索结果。

这里使用SQLite作为数据库,SQLite将所有信息都保存到一个文件,是一个易于安装和使用的数据库,不涉及数据库和服务器的配置,容易上手。SQLitet对应的Python版本是pysqlite,安装方法如下:

在官网下载pysqlite-2.8.3-cp27-cp27m-win_amd64.whl,然后通过下面命令安装。

pip install pysqlite-2.8.3-cp27-cp27m-win_amd64.whl

(1)imagesearch.py

创建表、索引和索引器Index类,以便将图像数据写入数据库。

from numpy import *
import pickle
from pysqlite2 import dbapi2 as sqliteclass Indexer(object):def __init__(self,db,voc):""" 初始化数据库的名称及词汇对象 """self.con = sqlite.connect(db)self.voc = vocdef __del__(self):self.con.close()def db_commit(self):self.con.commit()def get_id(self,imname):""" 获取图像id,如果不存在,就进行添加 """cur = self.con.execute("select rowid from imlist where filename='%s'" % imname)res=cur.fetchone()if res==None:cur = self.con.execute("insert into imlist(filename) values ('%s')" % imname)return cur.lastrowidelse:return res[0] def is_indexed(self,imname):""" 如果图像名字imname被索引到,就返回true """im = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone()return im != Nonedef add_to_index(self,imname,descr):""" 获取一幅带有特征描述子的图像,投影到词汇上并添加进数据库 """if self.is_indexed(imname): returnprint 'indexing', imname# 获取图像idimid = self.get_id(imname)# 获取单词imwords = self.voc.project(descr)nbr_words = imwords.shape[0]# 将每个单词与图像链接起来for i in range(nbr_words):word = imwords[i]# wordid就是单词本身的数字self.con.execute("insert into imwords(imid,wordid,vocname) values (?,?,?)", (imid,word,self.voc.name))# 存储图像的单词直方图# 用pickle模块将Numpy数组编码成字符串self.con.execute("insert into imhistograms(imid,histogram,vocname) values (?,?,?)", (imid,pickle.dumps(imwords),self.voc.name))def create_tables(self): """ 创建数据库表单 """self.con.execute('create table imlist(filename)')self.con.execute('create table imwords(imid,wordid,vocname)')self.con.execute('create table imhistograms(imid,histogram,vocname)')        self.con.execute('create index im_idx on imlist(filename)')self.con.execute('create index wordid_idx on imwords(wordid)')self.con.execute('create index imid_idx on imwords(imid)')self.con.execute('create index imidhist_idx on imhistograms(imid)')self.db_commit()class Searcher(object):def __init__(self,db,voc):""" 初始化数据库名称 """self.con = sqlite.connect(db)self.voc = vocdef __del__(self):self.con.close()def get_imhistogram(self,imname):""" 返回一幅图像的单词直方图 """im_id = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone()s = self.con.execute("select histogram from imhistograms where rowid='%d'" % im_id).fetchone()# 用pickle模块从字符串解码Numpy数组return pickle.loads(str(s[0]))def candidates_from_word(self,imword):""" 获取包含imword的图像列表 """im_ids = self.con.execute("select distinct imid from imwords where wordid=%d" % imword).fetchall()return [i[0] for i in im_ids]def candidates_from_histogram(self,imwords):""" 获取具有相似单词的图像列表 """# 获取单词idwords = imwords.nonzero()[0]# 寻找候选图像candidates = []for word in words:c = self.candidates_from_word(word)candidates+=c# 获取所有唯一的单词,并按出现次数反向排序 tmp = [(w,candidates.count(w)) for w in set(candidates)]tmp.sort(cmp=lambda x,y:cmp(x[1],y[1]))tmp.reverse()# 返回排序后的列表,最匹配的排在最后面return [w[0] for w in tmp] def query(self,imname):""" 查找所有与imname匹配的图像列表 """h = self.get_imhistogram(imname)candidates = self.candidates_from_histogram(h)matchscores = []for imid in candidates:# 获取名字cand_name = self.con.execute("select filename from imlist where rowid=%d" % imid).fetchone()cand_h = self.get_imhistogram(cand_name)cand_dist = sqrt( sum( self.voc.idf*(h-cand_h)**2 ) )matchscores.append( (cand_dist,imid) )# 返回排序后的距离及对应数据库ids列表matchscores.sort()return matchscoresdef get_filename(self,imid):""" 返回图像id对应的文件名 """s = self.con.execute("select filename from imlist where rowid='%d'" % imid).fetchone()return s[0]def tf_idf_dist(voc,v1,v2):v1 /= sum(v1)v2 /= sum(v2)return sqrt( sum( voc.idf*(v1-v2)**2 ) )def compute_ukbench_score(src,imlist):""" 对查询返回的前4个结果计算平均相似图像数,并返回结果 """nbr_images = len(imlist)pos = zeros((nbr_images,4))# 获取每幅查询图像的前4个结果for i in range(nbr_images):pos[i] = [w[1]-1 for w in src.query(imlist[i])[:4]]# 计算分数,并返回平均分数score = array([ (pos[i]//4)==(i//4) for i in range(nbr_images)])*1.0return sum(score) / (nbr_images)# import PIL and pylab for plotting
from PIL import Image
from pylab import *def plot_results(src,res):""" 显示在列表res中的图像 """figure()nbr_results = len(res)for i in range(nbr_results):imname = src.get_filename(res[i])subplot(1,nbr_results,i+1)imshow(array(Image.open(imname)))axis('off')show()

(2)创建索引

# -*- coding: utf-8 -*-
import pickle
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
from sqlite3 import dbapi2 as sqlite
from PCV.tools.imtools import get_imlist# 获取图像列表
imlist = get_imlist('pic150/')
nbr_images = len(imlist)
# 获取特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]# 载入词汇  读取再上一步中保存的.pkl文件
with open('vocabulary.pkl', 'rb') as f:voc = pickle.load(f)
# 创建索引器
indx = imagesearch.Indexer('testImaAdd.db',voc)
indx.create_tables()# 遍历所有的图像,并将它们的特征投影到词汇上
for i in range(nbr_images)[:1000]:locs,descr = sift.read_features_from_file(featlist[i])indx.add_to_index(imlist[i],descr)# 提交到数据库
indx.db_commit()
# 连接到数据库
con = sqlite.connect('testImaAdd.db')
# 数据库操作
print (con.execute('select count (filename) from imlist').fetchone())
print (con.execute('select * from imlist').fetchone())

运行结果:

创建索引,建立数据库testImaAdd.db。

3.2.3 在数据库中搜索图像

建立好图像索引,就可以在数据库中搜索相似图片了。

# -*- coding: utf-8 -*-
import pickle
from PCV.localdescriptors import sift
from PCV.imagesearch import imagesearch
from PCV.geometry import homography
from PCV.tools.imtools import get_imlist# 载入图像列表
imlist = get_imlist('pic150/')
nbr_images = len(imlist)
# 载入特征列表
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]# 载入词汇
with open('vocabulary.pkl', 'rb') as f:voc = pickle.load(f)src = imagesearch.Searcher('testImaAdd.db', voc)# 查询图像索引和查询返回的图像数
q_ind = 50
nbr_results = 20# 常规查询(按欧式距离对结果排序)
res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]]
print ('top matches (regular):', res_reg)# 载入查询图像特征
q_locs, q_descr = sift.read_features_from_file(featlist[q_ind])
fp = homography.make_homog(q_locs[:, :2].T)# 用单应性进行拟合建立RANSAC模型
model = homography.RansacModel()
rank = {}# 载入候选图像的特征
for ndx in res_reg[1:]:locs, descr = sift.read_features_from_file(featlist[ndx])  # because 'ndx' is a rowid of the DB that starts at 1# 获取匹配数matches = sift.match(q_descr, descr)ind = matches.nonzero()[0]ind2 = matches[ind]tp = homography.make_homog(locs[:, :2].T)# 计算单应性,对内点计数,若果没有足够的匹配数则返回空列表try:H, inliers = homography.H_from_ransac(fp[:, ind], tp[:, ind2], model, match_theshold=4)except:inliers = []# 存储内点数rank[ndx] = len(inliers)# 将字典排序,以有限获取最内层的内点数
sorted_rank = sorted(rank.items(), key=lambda t: t[1], reverse=True)
res_geom = [res_reg[0]] + [s[0] for s in sorted_rank]
print ('top matches (homography):', res_geom)# 显示查询结果
imagesearch.plot_results(src, res_reg[:8])  # 常规查询
imagesearch.plot_results(src, res_geom[:8])  # 重排后的结果

运行结果:(查询图片索引1)

图片索引1

常规查询结果

重排后查询结果

小结:

从查询结果可以看到,待查询的图片为一张猫的图片,前面数据集介绍的时候就有说每一类图片包含15张,也即有关猫的图片一共15张,在常规查询结果中可知,只有3张图片是与猫有关的,其中还有一张狗的图片,其它四张图片都是风景建筑,和猫没有半点联系和相似处,狗图片的出现,因猫狗两者都是动物,有一定的相似度,但是风景和建筑图片的出现偏差就太大了。再看重排后查询结果,前两张图片也是猫,但是第二张在常规查询结果中是第六个,现在提前了,相比于常规查询结果,重排查询的结构出现了更大误差,只有两张猫图片和一张狗图片。

课本数据集检索结果:

查询图片

常规查询结果

重排后查询结果

小结:

先介绍一下课本数据集,是肯塔基大学的物体识别数据集,一共有1000张图片,数据集比我的数据集大很多。从检测结果可知,常规查询结果和重排后查询结果所得的前三张图片是一样的,即这三张图片的相似度最高,也存在一定的偏差,后面五张图片都是与书不相关的图片,但是有一定的相似度。

该查询结果相比于我自己的数据集得到的查询结果,相似度图片有一定改善,这是因为数据集的原因,数据集越大,词汇量越丰富,类间差距相应减小,相似度升高。

4 总结

建立图像数据库,对图像进行索引就是从这些图像中提取描述子,利用词汇将描述子转换成视觉单词,并保存视觉单词及对应图像的单词直方图,从而可以利用图像对数据库进行查询,并返回相似的图像作为搜索结果。

如果图像数据库很大,逐一比较整个数据库中的所有直方图往往是不可行的,我们需要找到一个大小合理的候选集(这里的“合理”是通过搜索响应时间、所需内存等确定的),单词索引的作用便在于此:我们可以利用单词索引获得候选集,然后只需在候选集上进行逐一比较。

利用一些考虑到特征几何关系的准则重排搜索到的靠前结果,可以提高准确率。最常用的方法是在查询图像与靠前图像的特征位置间拟合单应性。为了提高效率,可以将特征位置存储在数据库中,并有特征的单词id决定它们之间的关联,要注意的是,只有在词汇足够大,使单词id包含很多准确匹配时,它才起作用。

在倒排表中,视觉单词包含的图像集合元素多,而且视觉单词数量多,因而在最后形成的直方图中,与其完全不相关的图像会因为视觉单词重合度大,而被排在前面,造成了输入和检测出的结果有偏差。

实验出现出现偏差的根本原因是数据库图像数目不够多,因而类间差距不够大,类内联系不够紧密,如果扩大图像库规模,会效果更好。

Bow模型的一个主要缺点是:在用视觉单词表示图像时,不包含图像特征的位置信息,这是为获取速度和可伸缩性而付出的代价。

计算机视觉8—基于BOW模型的图像检索和匹配相关推荐

  1. python计算机视觉--基于BOW模型的图像检索

    文章目录 原理解析 1.BOW模型 2.基于BOW的图像检索 2.1.用SIFT算法进行特征提取 2.2用K-means得出视觉词典 2.3.针对输入的特征集,根据视觉词典进行量化 2.4.把输入图像 ...

  2. Python计算机视觉之基于BOW的图像检索

    目录 一.图像检索 1.1 简介 1.2 步骤 二.Bag Of Words模型(BOW) 2.1 简介 2.2 原理 2.2.1 特征提取 2.2.2 学习"视觉词典" 2.2. ...

  3. 计算机视觉:基于BOW的图像检索与识别

    目录 一.基础简介 二.实验步骤 1.特征提取 2.学习"视觉词典(visual vocabulary)" 3.根据IDF原理,计算视觉单词的权 4.针对特征集,根据视觉词典进行量 ...

  4. BoW模型用于图像检索的一般化流程

    --来自肉麻的开题报告 以经典BoW模型实现一个图像检索的方法,BoW检索的一般流程如图2所示: 图2  BoW检索流程 最初的BoW在图像检索中应用的流程主要分为以下几步: 1.特征提取.在训练阶段 ...

  5. 【计算机视觉】基于BOW的图像检索

    一.图像检索概述 简单的说便是从图片检索数据库中检索出满足条件的图片,图像检索技术的研究根据描述图像内容方式的不同可以分为两类:一类是基于文本的图像检索技术,一类为基于内容的图像检索技术.它最早用于对 ...

  6. Python计算机视觉(五)——基于BOW的图像检索

    文章目录 一.图像搜索 二.BOW模型图像检索 1.BOW(Bag-of-words) 2.Bag-of-features 三.算法流程 1.特征提取 2.学习"视觉词典"(vis ...

  7. python计算机视觉--基于(BOW)的图像检索与识别

    目录 前言 一.基本原理 1.1 图像分类简介 1.2 Bag-of-words模型 1.3 Bag-of-features模型 1.4  Bag-of-features算法 1.5  Bag-of- ...

  8. 基于BOW的图像检索 【计算机视觉第七章】

    目录 BOW简介 基于BOW的图像检索流程 1. 特征提取 (SIFT) 2. 学习 "视觉词典(visual vocabulary)" (k-means) 3. 针对输入特征集, ...

  9. 计算机视觉—基于BOW的图像检索

    基于BOW的图像检索 1. 基本原理 1.1 Bag-of-words原理简介 1.2 Bag-of-features原理简介 1.3 Bag-of-features算法 1.3.1 图像检索流程 1 ...

最新文章

  1. 互联网黄金十年的黄昏——是人工智能的黎明还是裁员的长夜
  2. java初学之stream
  3. [网摘]CSS z-index 属性
  4. LeetCode之最大回文串--动态规划
  5. 媒体智能-淘宝直播流媒体互动实践 | D2 分享视频+文章
  6. 听说IT人的目标都是成为架构师,那么请收下这份架构养成计划
  7. Java中super与this
  8. 信息学奥赛一本通 1034:计算三角形面积 | OpenJudge NOI 1.3 17
  9. C语言和设计模式(装饰模式)
  10. POJ 1716 Integer Intervals
  11. moonmq: 用go实现的高性能message queue
  12. 精通~Scrum为什么会转型困难
  13. 拓端tecdat|Python中的Apriori关联算法-市场购物篮分析
  14. 434.字符串中的单词数
  15. 在Idea中拉取svn分支
  16. tiff格式转为jpg,tiff转jpg方法
  17. 2、硬件工程师之元器件学习—电阻(二)
  18. 元宇宙地产演化史:从文本时代到区块链时代
  19. 基于单片机1KW高频感应加热器控制系统仿真设计(毕设)
  20. 无法唤起订阅消息弹窗 requestSubscribeMessage:fail can only be invoked by user TAP gesture

热门文章

  1. 目标检测数据集-Pascal VOC 数据集介绍
  2. cad旋转命令_寮步CAD电脑培训班寮步消防附近的电脑培训班
  3. 开源免费企业平台Odoo的简介和应用
  4. No.77 组合:回溯法
  5. 纯CSS实现逼真翻页时钟
  6. 如何为PDF文件添加注释?
  7. linux毫秒时间差计算,shell脚本示例:计算毫秒级、微秒级时间差
  8. “无实物尝百味”通过控制微电流刺激产生味觉—2.环境搭建篇
  9. 仿抖音 快手 小火山等短视频APP
  10. (16)调度代码周期性运行