python计算机视觉学习第七章——图像搜索

article/2025/7/16 9:57:56

目录

一、基于内容的图像检索

二、 视觉单词

三、 图像索引 

3.1 建立数据库

3.2 添加图像 

​编辑四、在数据库中搜素图像 

4.1 利用索引获取候选图像

4.2 用一幅图像进行查询 

4.3 确定对比基准并绘制结果 

五、 使用几何特性对结果排序


一、基于内容的图像检索

        CBIR技术用于检索在视觉上具有相似性的图像,返回的图像可以是颜色相似、纹理相似、图像中的物体或场景相似。对于高层查询,比如寻找相似的物体,将查询图像与数据库中所有的图像进行完全比较往往是不可行的,因为当数据库很大时,这种查询方式会耗费很长的时间。不过,研究者目前已经成功地引入文本挖掘技术到CBIR中处理问题,因此在数百万图像中搜索具有相似内容的图像成为了可能。

        矢量空间模型

        矢量空间模型是一个用于表示和搜索文本文档的模型。它基本上可以应用于任何对象类型,包括图像。矢量空间模型的名字来源于用矢量表示文本文档,这些矢量是由文本词频直方图构成,即矢量包含了每个单词出现的次数,且在其他别的地方包含了很多0元素。由于其忽略了单词出现的顺序及位置故也称为BOW表示模型。

        通过单词计数来构建文档直方图向量v,从而建立文档索引。由于每篇文档的长度不同,因此除以直方图总和将向量归一化成单位长度。对于直方图向量中的每个元素,一般根据每个单词的重要性来赋予相应的权重。

        常用的权重是tf-idf,单词w在文档d中的词频是:

n_{w}是单词w在文档d中出现的次数。为了归一化,将n_{w}除以整个文档中单词的总数。逆向文档频率就为:

\left | D \right |是在语料库D中文档的数目,分母是语料库中包含单词w的文档数d。将两者相乘就可以得到矢量v中对应元素的tf-idf权重。

二、 视觉单词

        可以利用SIFT局部描述子建立视觉等效单词,从而将文本挖掘技术应用到图像中。它的思想是将描述子空间量化成一些典型实例,并将图像中的每个描述子指派到其中的某个实例中,这些典型实例可以通过分析训练图像集确定,并被视为视觉单词。视觉单词组成的集合称为视觉词汇,亦或者视觉码本。

        从一个很大的训练图像集提取特征描述子,利用一些聚类算法就可以构建出视觉单词,聚类算法中最常用的是K-means,这时得到的视觉单词是聚类质心。这里使用的数据集是书中给出的肯塔基大学物体识别数据集。可以在上一章给出的链接里下载得到。

        创建词汇

        创建视觉单词词汇,首先要提取特征描述子,这里使用的是SIFT特征描述子。由于提供的图片太多这里就选取了其中的109幅图像。

from PCV.tools import imtools
from PCV.localdescriptors import siftimlist = imtools.get_imlist('D:\\picture\\first1000\\')
nbr_images = len(imlist)
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]
for i in range(nbr_images):sift.process_image(imlist[i], featlist[i])

之后创建名为vocabulary,py文件,创建一个词汇类,以及在训练图像数据集上训练出一个词汇的方法:

class 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 imhist

这个类中包含了一个由单词聚类中心VOC与每个单词对应的逆向文档频率构成的向量,为了在某些图像集上训练词汇,train()方法获取包含由.sift描后缀的述子文件列表和词汇单词数k。我们可以在K-means聚类阶段对训练数据下采样,避免消耗过多时间。

接着保存视觉词汇:

import pickle
from PCV.imagesearch import vocabulary
from PCV.tools import imtoolsimlist = imtools.get_imlist('D:\\picture\\first1000\\')
nbr_images = len(imlist)
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]voc = vocabulary.Vocabulary('ukbenchtest')
voc.train(featlist, 1000, 10)
# 保存词汇
with open('vocabulary.pkl', 'wb') as f:pickle.dump(voc, f)
print('vocabulary is:', voc.name, voc.nbr_words)

三、 图像索引 

3.1 建立数据库

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

        使用SQLite作为数据库,SQLite将所有信息都保存到一个文件,在pycharm中可以直接通过settings里的python interpreter 进行安装。

        创建一个imagesearch.py的文件:

    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()

使用pickle模块将数组编码成字符串以及将字符串进行解码,SQLite可以从sqlite3模块中导入,上述方法存在indexer类中,创建之后就可以保存词汇对象。__del__()方法确保关闭数据库连接,db_commit()可以将更改写入数据库文件。

下面为存储图像及视觉单词的简单数据库模式:

lmlist包含所有要索引的图像文件名,imwords包含了单词的单词索引、用到了哪个词汇、以及单词出现在哪些图像中,imhistograms包含了全部每幅图像的单词直方图。

在indexer类中添加下面的代码可以加快搜索速度:

    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()

3.2 添加图像 

        在创建完数据库表单后,就可以在索引中添加图像,这里要在indexer类中添加add_to_index()方法,

    def 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))

这个方法获取图像文件名与Numpy数组,该数组包含的是在图像找到的描述子。这些描述子投影到词汇上,并插入到imwords和imhistograms表单中。通过使用辅助函数is_indexed()检查图像是否以及被索引以及get_id()对一幅图像文件名给定id好。

    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):""" 当图像名字被索引返回True """im = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone()return im != None

由于SQLite的数据库在存储对象或数组时并没有一个标准类型,因此使用pickle的dumps()函数创建一个字符串表示并将其写入数据库。

实验:

遍历整个文件数据库中的样本图像,并为其添加索引:

import pickle
from PCV.tools import imtools
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
imlist = imtools.get_imlist('D:\\picture\\first1000\\')
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)# 创建索引器
indx = imagesearch.Indexer('test.db',voc)
indx.create_tables()# 遍历这个图像库,将特征投影到词汇上并添加到索引中
for i in range(nbr_images)[:109]:locs,descr = sift.read_features_from_file(featlist[i])indx.add_to_index(imlist[i],descr)
# 提交到数据库
indx.db_commit()

接着数据库的内容进行检查:

from sqlite3 import dbapi2 as sqlitecon = sqlite.connect('test.db')
print(con.execute('select count (filename) from imlist').fetchone())
print(con.execute('select * from imlist').fetchone())

就可以得到下面的结果,这里得到图像数为109幅,以及其保存的位置。 

四、在数据库中搜素图像 

        建立好图像的索引后,就可以在数据库中搜索相似的图像了,书中使用的是BoW来表示整个图像,为了实现搜索,在imagesearch.py中添加Scanner类。

class Searcher(object):def __init__(self,db,voc):""" 初始化数据库的名称 """self.con = sqlite.connect(db)self.voc = vocdef __del__(self):self.con.close()

当一个新的searcher对象连接到数据库时,一旦删除就关闭连接。 

4.1 利用索引获取候选图像

        可以利用建立起来的索引找到包含特定单词的所有图像,这是对数据库的一次简单的查询,在Searcher类中加入candidates_from_word()方法:  

    def candidates_from_word(self,imword):""" G获取包含imword的图像列表 """im_ids = self.con.execute("select distinct imid from imwords where wordid=%d" % imword).fetchall()return [i[0] for i in im_ids]

上述函数会给出包含特定单词的所有图像id号。为了对合并了的列表中的每一幅图像id出现的次数进行跟踪,这样做就可以显示有多少单词与单词匹配直方图中的单词匹配,这个过程通过candidates_from_histogram方法完成:

    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] 

上述方法从图像单词直方图的非零项创建单词id列表,检索每个单词获得候选集并将其合并到candidates列表中,然后创建一个元组列表每个元组由单词id和次数count构成,count是候选列表中每个单词出现的次数。同时,还以元组中的第二个元组为准,用sort()方法和一个自定义的比较函数对列表进行排序。

4.2 用一幅图像进行查询 

        在利用一幅图像进行查询时,就没有必要进行完全的搜索,为了对单词直方图进行比较Searcher类就需要从数据库中读入图像的单词直方图。

    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] 

为了在字符串与Numpy数组间进行转换,再次使用到了pickle模块,这里用到的是loads()方法。

    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模块从字符串解码Numpyreturn pickle.loads(str(s[0]))

合并到查询方法中:

    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)# 用L2距离度量相似性cand_dist = sqrt( sum( self.voc.idf*(h-cand_h)**2 ) )matchscores.append( (cand_dist,imid) )# 返回排序后的距离及对应数据库ids列表matchscores.sort()return matchscores

query()方法获取图像的文件名,检索其单词直方图及候选图像列表。对于每一个候选图像,我们用标准的欧式距离比较他和查询图像间的直方图,并放回一个经排序的包含距离及图像的id的元组列表。

尝试查询:

import pickle
from PCV.tools import imtools
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
imlist = imtools.get_imlist('D:\\picture\\first1000\\')
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('test.db', voc)
print('try a query....')
print(src.query(imlist[0])[:10])

这里需要注意一下,在上面candidates_from_histogram()的代码中,书中使用的是python3.6版本以前的方法,给出的排序方法是

tmp.sort(cmp=lambda x,y:cmp(x[1],y[1]))

但cmp方法在python3.6版本之后就弃用了,此时使用时会出现报错的现象,因此需要对其进行更改,查阅资料后发现3.6版本后可以通过使用import functools中的cmp_to_key来实现。将代码改成:

import functools
tmp.sort(key=functools.cmp_to_key(lambda x,y:(x[1] - y[1])))

此时代码运行后的结果为: 

这里给出了10个结果,距离为0的图像对于查询图像本身;三幅与查询图像具有相同场景的图像有两幅在除查询图像本身外的前两个位置,第三幅则出现在第五个位置。

4.3 确定对比基准并绘制结果 

        为评价搜索结果的好坏,可以计算前4个位置中搜索到相似图像数。计算分数的函数为:

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)

获取搜素的前4个结果,将query()返回的索引减去1,因为数据库索引是从1开始的,而图像列表的索引是从0开始的。利用每4幅图像为一组时相似图像文件名是连续的这一事实,用整数相除计算得到最终的分数。分数为4时结果最为理想;没有一个是准确的时,分数为0;仅检索到相同图像时,分数为1,当找到相同的图像并且其他三个中的两个相同时,分数为3。

        显示实际搜素结果:

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()

实验:

import pickle
from PCV.tools import imtools
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
imlist = imtools.get_imlist('D:\\picture\\first1000\\')
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('test.db', voc)
nbr_results = 6
res = [w[1] for w in src.query(imlist[0])[:nbr_results]]
imagesearch.plot_results(src,res)

结果如下图所示:

上图中第一幅图是拿出来查询的图,后面的都是相似的图,前三幅最为相似。

五、 使用几何特性对结果排序

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

        这里实验一下载入所有模型文件并用单应性对靠前的图像进行重排的完整例子:

import pickle
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
from PCV.geometry import homography
from PCV.tools import imtools
imlist = imtools.get_imlist('D:\\picture\\first1000\\')
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('test.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])# 获取匹配数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])  # 重排后的结果

这里就可以很号的看出第二次的查询结果更加准确。 


http://chatgpt.dhexx.cn/article/cEwBbvH6.shtml

相关文章

使用计算机视觉和深度学习创建现代OCR管道

作者 | 学海无涯yc 编辑 | 3D视觉开发者社区 文章目录 前言1.研究和原型设计2.字深网3.字检测器4.组合式端到端系统5.生产化6.性能调优7.优雅 导读 此篇文章中讲述使用了计算机视觉和深度学习的进步,如双向长短期记忆(LSTM),连接…

Java OCR tesseract 图像智能字符识别技术

公司有需求啊,所以就得研究哈,最近公司需要读验证码,于是就研究起了图像识别,应该就是传说中的(OCR:光学字符识别OCR),下面把今天的收获整理一个给大家做个分享。 本人程序用的tess…

《深度学习中的字符识别在工业视觉中的实际应用》

最近在公司做了一个构建卷积神经网络来识别字符的项目,编程环境为pycharm2019,使用的是OpenCvPytorch进行项目的实现,因此想总结和归纳一下方法。 本次的字符识别项目可以分为以下几个步骤: 一、图像处理和字符分割 二、创建自…

python计算机视觉-图像检索和识别

目录 一、原理解析 1.1计算机视觉领域的图像分类是什么意思? 1.2图像分类要如何实现? 1.3Bag-of-features算法和过程? 1)提取图像特征 2)训练字典( visual vocabulary ) 3)图片直方图表示 4)训练分类器 1.4TF-IDF? 1.5当前图像分类中会遇到…

使用计算机视觉和深度学习创建现代 OCR 管道

文章目录 研究和原型设计字深网字检测器组合式端到端系统生产化性能调优优雅 在这篇文章中,我们将带您了解我们如何为[【移动文档扫描仪】构建最先进的光学字符识别(OCR)管道的幕后故事。我们使用了计算机视觉和深度学习的进步,如…

最流行的4个机器学习数据集

最流行的4个机器学习数据集 机器学习算法需要作用于数据,而数据的本质则决定了应用的机器学习算法是否合适,而数据的质量也会决定算法表现的好坏程度。所以会研究数据,会分析数据很重要。本文作为学习研究数据系列博文的开篇,列举…

机器学习——数据集预处理(数据查看和空值处理)

目录 前言 数据集查看 前言 目的:本数据集是为了分析炉丝功率和炉膛温度以及样品盒内部温度之间的关系,分析温场的分布等。 来源:本数据集的来源是实验获得的数据。 特点:特征维度高,数据量大。 数据集查看 1.查…

推荐收藏:50个最佳机器学习公共数据集

外国自媒体mlmemoirs根据github、福布斯、CMU官网等信息,整理了一张50个最佳机器学习公共数据集的榜单,为大家分享一下~ 作者:mlmemoirs 郭一璞 编译 外国自媒体mlmemoirs根据github、福布斯、CMU官网等信息,整理了一张50个最佳…

8种适用于不同机器学习问题的常用数据集

要找到一定特定的数据集可以解决各种机器学习问题,是一件很难的事情。越来越多企业或研究机构将自己的数据集公开,已经成为全球的趋势,这也将有助于大家进行更多研究。 近期,亚马逊高级技术顾问 Will Badr 分享了 8 种适用于不同…

【ML】机器学习数据集:sklearn中回归数据集介绍

目录 1. Boston房价预测数据集2. California房价预测数据集3. 糖尿病预测数据集 在机器学习的教程中,我们会看到很多的demo,这些demo都是基于python中自带的数据集。今天我们将介绍三个用于回归预测的数据集。 1. Boston房价预测数据集 该数据集将在sci…

浅谈机器学习之数据集构建

浅谈机器学习之数据集构建 ​ 正如大家现在知道的,深度学习模型(DL)和机器学习模型(ML)是数据驱动型任务,在近乎完美的数据集面前,模型间的细微差异可以忽略。但要获得覆盖目标场景所有特征的样本,不仅要耗费巨大的人力物力&…

机器学习经典开源数据集盘点

在机器学习任务实施前,如何快速寻找到可用数据集,是令每一位研究人员最头痛的事情。本文为大家列举了八大主流数据集来源,不仅包含大量的数据集信息,而且包含了描述、用法以及一些实施案例等。 01 Kaggle数据集 Kaggle数据集地址h…

免费的机器学习数据集网站(6300+数据集)

今天给大家分享一个免费获取机器学习数据集网站: Machine Learning Datasets | Papers With Code 有想法但没有数据集的同学的福音,网站届满很简洁,及本本上提供的了一般可用的各类数据集,我们可以进行各类影像、评论和点云等数…

学习机器学习算法过程中的常用数据集

文章目录 【数据集1】forge:小型模拟分类问题数据集【数据集2】wave:小型模拟回归问题数据集【数据集3】cancer:中型实际分类问题数据集【数据集4】boston:中型实际回归问题数据集 以下数据集为学习机器学习算法时,经常…

虚拟机系统iso镜像下载_如何下载正版系统镜像

许多网友想装系统,可是不会装(后期会推装系统的文章),而且网上的系统有的装有全家桶,有的又有捆绑软件,严重的还有病毒。那么,在哪里去下载正版,安全的系统镜像呢 "MSDN,我告诉你"这个…

Win7下安装xp虚拟机

在win7下安装Oracle VM VirtualBox虚拟机,然后在安装xp程序。 准备工作: 1. Oracle VM VirtualBox虚拟机 2. 一张xp安装版的镜像盘(这里一定是安装版而不是Ghost版,如果想知道ghost版的会出现什么问题,不妨自己试试。&…

虚拟机系统iso镜像下载_[原版镜像]macOS Mojave 10.14.1 原版 iso 镜像- 虚拟机专用

[原版镜像]macOS Mojave 10.14.1 原版 iso 镜像- 虚拟机专用 Notes: 1. 此镜像仅供用于虚拟机安装, 不能制作启动 u 盘. 2. 此镜像和专栏文章: macOS Mojave 10.14.2 原版镜像 皆可用于虚拟机安装 macOS. 另: 此镜像为苹果官方免费 macOS 镜像和工具制作而成, 没有任何第三方内…

微软官方提供的免费正版 Windows 8.1/Win10/7/XP/Vista 操作系统虚拟机镜像下载

微软官方提供的免费正版 Windows 8.1/Win10/7/XP/Vista 操作系统虚拟机镜像下载 https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ 相信做过网页开发/前端的同学都知道,测试各个浏览器的兼容性是最麻烦的事情之一,单单 IE 就有 N 个版…

基于snap7在vs上通信

这是个已有的snap7通信示例: 首先你得有visual studio,然后 1.在snap7官网上下载文件snap7-full-1.4.2 2.打开snap7-full-1.4.2\examples\dot.net\WinForm\CSharp\CSharp.sln 3.直接编译,它会报错 具体正确的解决方法不太懂,我就…

Snap7 西门子S7系列PLC的通信库 简介

目录 简介参考Snap7 简介Snap7 用途适用系统支持语言西门子S7通信介绍Snap7 组件Sanp7 API源码、手册、样例下载 简介 最近在开发一个项目,作为技术帝,已经完成工艺、机械设计的设计,项目过多,也是为了让自己更加?叉&#xff0c…