下面为您介绍“python爬取NUS-WIDE数据库图片”的完整攻略,包含两条示例说明。
简介
NUS-WIDE是一个包含269,648张图片的数据库,图片来源于Flickr社交网站。这些图片被手工标注为38个不同的标签。这个数据库可以用于图像检索、多标签分类、语义注释等领域的研究。
在使用NUS-WIDE数据库进行研究时,我们通常需要把图片下载到本地。本文将介绍如何使用Python爬取NUS-WIDE数据库图片。
步骤
1. 下载NUS-WIDE数据库
首先,你需要到NUS-WIDE官网http://lms.comp.nus.edu.sg/research/NUS-WIDE.htm上下载NUS-WIDE数据库。在下载页面上,你需要填写一个表单并提交。提交成功后,你将收到一封包含下载链接的邮件。
2. 解压数据库文件
你需要将下载的压缩文件解压到本地的某个目录中。解压后的文件夹包含了10个MATLAB文件,其中每个文件对应一个图片标签。在这些MATLAB文件中,每个变量都是一个结构体,包含图片的文件名、标签等信息。
3. 安装必要的Python库
接下来,你需要安装必要的Python库:numpy、h5py、Pillow、beautifulsoup4和requests。这些库都可以通过pip安装。
pip install numpy
pip install h5py
pip install Pillow
pip install beautifulsoup4
pip install requests
4. 编写爬虫程序
为了爬取NUS-WIDE数据库的图片,我们需要编写一个Python程序。代码如下:
import h5py
import os
import requests
from PIL import Image
from io import BytesIO
from bs4 import BeautifulSoup
# 数据库文件夹路径
database_dir = './database'
# 数据库文件名称
database_file = 'NUS-WIDE-Object-Database.mat'
# 图片存放路径
img_dir = './img'
os.makedirs(img_dir, exist_ok=True)
with h5py.File(os.path.join(database_dir, database_file), 'r') as f:
# 遍历每个MATLAB文件
for label in f.keys():
label_dir = os.path.join(img_dir, label)
os.makedirs(label_dir, exist_ok=True)
# 遍历当前标签下的所有图片,读取图片内容并保存为文件
for img_name in f[label]['filename']:
url = 'https://farm{}.staticflickr.com/{}/{}.jpg'.format(f[label]['farm'][0], f[label]['server'][0], img_name)
response = requests.get(url)
img = Image.open(BytesIO(response.content))
img.save(os.path.join(label_dir, img_name + '.jpg'))
print('Downloaded image ' + img_name)
这个程序遍历数据库文件夹中的每个MATLAB文件,读取其中的图片数据并保存为本地文件。
5. 运行爬虫程序
在程序执行之前,请确保你已经将NUS-WIDE数据库解压到了本地。另外,如果你需要在程序中使用代理服务器,请设置requests库的代理。
使用命令行进入Python所在的目录,并运行程序:
python nuswide_spider.py
程序会依次下载NUS-WIDE数据库中的所有图片,并将它们保存在本地的相应标签文件夹中。
示例
下面以两个示例展示如何使用NUS-WIDE数据库和爬虫程序。
示例1: 使用NUS-WIDE数据库进行多标签分类
假设我们要使用NUS-WIDE数据库进行多标签分类的研究。首先,我们需要将数据库图片下载到本地。请按照上面的步骤下载NUS-WIDE数据库,并使用爬虫程序将数据库中的图片下载到本地。
接下来,我们需要将图片分割成训练集和测试集,并使用神经网络模型训练和测试。这个过程可以使用Python的深度学习库Keras实现。另外,我们需要使用sklearn库对模型进行评估。
import os
import random
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import Adam
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.model_selection import train_test_split
# 图片文件夹路径
img_dir = './img'
# 图片尺寸(像素)
img_size = 224
# 批处理大小
batch_size = 32
# 训练集比例
train_ratio = 0.8
# 加载图片数据
X, y = [], []
for i, label in enumerate(os.listdir(img_dir)):
for img_name in os.listdir(os.path.join(img_dir, label)):
img_path = os.path.join(img_dir, label, img_name)
img = Image.open(img_path).resize((img_size, img_size))
X.append(np.array(img))
y.append(np.zeros((38,)))
y[-1][i] = 1
# 将数据分割成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=train_ratio, random_state=42)
# 构建神经网络模型
model = Sequential([
Dense(512, input_shape=(img_size, img_size, 3), activation='relu'),
Dropout(0.2),
Dense(512, activation='relu'),
Dropout(0.2),
Dense(38, activation='softmax')
])
model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.001), metrics=['accuracy'])
# 训练模型
model.fit(np.array(X_train), np.array(y_train), batch_size=batch_size, epochs=10, validation_data=(np.array(X_test), np.array(y_test)))
# 测试模型
y_pred = model.predict(np.array(X_test))
y_pred_labels = np.argmax(y_pred, axis=1)
y_true_labels = np.argmax(y_test, axis=1)
print(classification_report(y_true_labels, y_pred_labels))
print(confusion_matrix(y_true_labels, y_pred_labels))
这个程序使用载入的图片数据构建了一个三层的神经网络,其中前两层是密集层(Dense),第三层是softmax层。模型以categorical_crossentropy损失函数、Adam优化器和准确率指标为评价标准,使用训练集训练10个epochs。训练完毕后,模型使用测试集进行评价,打印出分类报告和混淆矩阵。
示例2: 使用NUS-WIDE数据库进行图像检索
假设我们要使用NUS-WIDE数据库进行图像检索的研究。首先,我们需要将数据库图片下载到本地。请按照上面的步骤下载NUS-WIDE数据库,并使用爬虫程序将数据库中的图片下载到本地。
接下来,我们需要将每张图片的特征提取出来,并建立一个图像检索系统。这个过程可以使用Python的深度学习库Keras实现。
import os
import numpy as np
from keras.applications.vgg16 import VGG16, preprocess_input
from keras.preprocessing import image
from sklearn.neighbors import NearestNeighbors
# 图片文件夹路径
img_dir = './img'
# 图片尺寸(像素)
img_size = (224, 224)
# 特征向量维度
feat_dim = 4096
# 图像检索算法(k-近邻)
k = 5
# 构建卷积神经网络模型
model = VGG16(weights='imagenet', include_top=False, input_shape=(img_size[0], img_size[1], 3))
# 加载图片特征
X, img_paths = [], []
for i, label in enumerate(os.listdir(img_dir)):
for img_name in os.listdir(os.path.join(img_dir, label)):
img_path = os.path.join(img_dir, label, img_name)
img = image.load_img(img_path, target_size=img_size)
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
img = preprocess_input(img)
X.append(model.predict(img)[0].reshape((feat_dim,)))
img_paths.append(img_path)
# 训练k-近邻算法
knn = NearestNeighbors(n_neighbors=k, algorithm='brute', metric='cosine')
knn.fit(X)
while True:
# 读取输入图片
query_path = input('Enter the path of the query image: ')
query_img = image.load_img(query_path, target_size=img_size)
query_img = image.img_to_array(query_img)
query_img = np.expand_dims(query_img, axis=0)
query_img = preprocess_input(query_img)
query_feat = model.predict(query_img)[0].reshape((feat_dim,))
# 进行图像检索
dists, indices = knn.kneighbors(query_feat.reshape((1, -1)))
# 展示检索结果
query_url = 'file://' + os.path.abspath(query_path)
print('\nQuery image: ' + query_url + '\n')
for i, idx in enumerate(indices[0]):
img_path = img_paths[idx]
img_url = 'file://' + os.path.abspath(img_path)
print('Rank {}: '.format(i+1) + img_url)
这个程序首先使用VGG16模型对每张图片提取出其特征向量。然后,程序构建了一个k-近邻模型并训练之。训练完成后,程序从命令行读取输入,查询输入的图片在数据库中最相似的k张图片。查询结果按相似度从高到低排列,然后展示查询图片和检索结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python爬取NUS-WIDE数据库图片 - Python技术站