Notes
想调用 keras 的预训练网络提取图像特征,其中 VGG 和 ResNet50 要求输入图像长宽是224 x 224
,以 CUB 数据集为例,预处理图片尺寸,放到一个新文件夹里。
Dataset
Caltech-UCSD Birds 200
CUB 数据库有分 2010 版和 2011 版的,官网左侧边栏可选,都是 200 个类,其中:
- 2010 版:Caltech-UCSD Birds 200
- Number of categories: 200
- Number of images: 6,033
- Annotations: Bounding Box, Rough Segmentation, Attributes
- 2011 版:The Caltech-UCSD Birds-200-2011 Dataset
- Number of categories: 200
- Number of images: 11,788
- Annotations per image: 15 Part Locations, 312 Binary Attributes, 1 Bounding Box
本篇示例用的是 2011 版,下载解压后,images/
子目录里是按类组织的图片,一个类一个文件夹,文件夹名就是类名。更多介绍可见其README
文件。
Pitfall
有个坑在于数据集里并不是所有图片都是彩色的,比如009.Brewer_Blackbird
类的Brewer_Blackbird_0028_2682.jpg
一图,黑白图读出来没有 channel 这一维。开始没注意到这个问题,结果后续处理报错了。
我的处理办法:用 numpy 建一个目标尺寸的、通道数为 3 的数组(本示例中即224 x 224 x 3
),每个通道都赋成那张黑白图的值,这样能扩展出 channel 这维,且与原来的黑白图一致。原理可能是三种色光混合就变成白色光之类的。详见代码。
Code
目标:将图像尺寸改成224 x 224
,放在一个新目录下(如:images.resized/
),跟原来images/
的组织方式相同。
# -*- coding: utf8 -*-
from os.path import join
from os import listdir, makedirs
from imageio import imread, imwrite
from scipy.misc import imresize #, imread, imsave
import numpy as np
IN = 'images' # 源目录
OUT = 'images.resized' # 输出目录
CHANNEL = 3 # 通道数
SIZE_2D = (224, 224) # 目标长宽
SIZE_3D = (224, 224, CHANNEL)
makedirs(OUT) # 创建输出目录
ls = list(listdir(IN)) # 列出(按类组织的)子目录
# print(ls)
for p in ls:
out_d = join(OUT, p) # 输出(按类组织的)子目录
makedirs(out_d)
p = join(IN, p)
# print(listdir(p))
for filE in listdir(p):
img = imread(join(p, filE)) # 读图
img = imresize(img, SIZE_2D) # 改图
if img.shape != SIZE_3D: # 黑白图
tmp = np.zeros(SIZE_3D)
for c in range(CHANNEL):
tmp[:, :, c] = img
img = tmp
imwrite(join(out_d, filE), img) # 存图
Files
百度网盘:https://pan.baidu.com/s/12Frox4ztNmH5E_ZERlRwjg?pwd=7zdh
,提取码:7zdh
。
References
SciPy快速入门教程
Imageio’s user API
Applications | Keras Documentation
keras预训练模型应用(3):VGG19提取任意层特征