举个例子,提取全部可能的标签,以0.5为阈值
# -*- coding: utf-8 -*-import i2vfrom imageio import imreadillust2vec = i2v.make_i2v_with_chainer('illust2vec_tag_ver200.caffemodel', 'tag_list.json')img = imread('imgs/二次元头像示例.jpg')tags = illust2vec.estimate_plausible_tags([img], threshold=0.5)print(tags)tags = illust2vec.estimate_specific_tags([img], ['blue eyes', 'red hair'])print(tags)复制代码也可以指定标签并获取对应的概率
[{'blue eyes': 0.9488178491592407, 'red hair': 0.0025324225425720215}]复制代码预处理在服务器上处理全部图片,即截取头像、提取标签
加载库
# -*- coding: utf-8 -*-import i2vimport cv2import globimport osfrom imageio import imreadfrom tqdm import tqdmimport matplotlib.pyplot as plt%matplotlib inlineimport numpy as npimport pickle复制代码读取图片路径
images = glob.glob('characters/*.jpg')print(len(images))复制代码加载两个模型
illust2vec = i2v.make_i2v_with_chainer('illust2vec_tag_ver200.caffemodel', 'tag_list.json')cascade = cv2.CascadeClassifier('lbpcascade_animeface.xml')OUTPUT_DIR = 'faces/'if not os.path.exists(OUTPUT_DIR): os.mkdir(OUTPUT_DIR)复制代码提取全部头像,共检测到27772张
num = 0for x in tqdm(range(len(images))): img_path = images[x] image = cv2.imread(img_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.equalizeHist(gray) faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(64, 64)) for (x, y, w, h) in faces: cx = x + w // 2 cy = y + h // 2 x0 = cx - int(0.75 * w) x1 = cx + int(0.75 * w) y0 = cy - int(0.75 * h) y1 = cy + int(0.75 * h) if x0 < 0: x0 = 0 if y0 < 0: y0 = 0 if x1 >= image.shape[1]: x1 = image.shape[1] - 1 if y1 >= image.shape[0]: y1 = image.shape[0] - 1 w = x1 - x0 h = y1 - y0 if w > h: x0 = x0 + w // 2 - h // 2 x1 = x1 - w // 2 + h // 2 w = h else: y0 = y0 + h // 2 - w // 2 y1 = y1 - h // 2 + w // 2 h = w face = image[y0: y0 + h, x0: x0 + w, :] face = cv2.resize(face, (128, 128)) cv2.imwrite(os.path.join(OUTPUT_DIR, '%d.jpg' % num), face) num += 1print(num)复制代码感兴趣的标签包括以下34个:
13种头发颜色:blonde hair, brown hair, black hair, blue hair, pink hair, purple hair, green hair, red hair, silver hair, white hair, orange hair, aqua hair, grey hair
5种发型:long hair, short hair, twintails, drill hair, ponytail
10种眼睛颜色:blue eyes, red eyes, brown eyes, green eyes, purple eyes, yellow eyes, pink eyes, aqua eyes, black eyes, orange eyes
6种其他属性:blush, smile, open mouth, hat, ribbon, glasses
头发颜色、发型和眼睛颜色取概率最高的一种,其他属性概率高于0.25则以存在处理
fw = open('face_tags.txt', 'w')tags = ['blonde hair', 'brown hair', 'black hair', 'blue hair', 'pink hair', 'purple hair', 'green hair', 'red hair', 'silver hair', 'white hair', 'orange hair', 'aqua hair', 'grey hair', 'long hair', 'short hair', 'twintails', 'drill hair', 'ponytail', 'blue eyes', 'red eyes', 'brown eyes', 'green eyes', 'purple eyes', 'yellow eyes', 'pink eyes', 'aqua eyes', 'black eyes', 'orange eyes', 'blush', 'smile', 'open mouth', 'hat', 'ribbon', 'glasses']fw.write('id,' + ','.join(tags) + '\n')images = glob.glob(os.path.join(OUTPUT_DIR, '*.jpg'))for x in tqdm(range(len(images))): img_path = images[x] image = imread(img_path) result = illust2vec.estimate_specific_tags([image], tags)[0] hair_colors = [[h, result[h]] for h in tags[0:13]] hair_colors.sort(key=lambda x:x[1], reverse=True) for h in tags[0:13]: if h == hair_colors[0][0]: result[h] = 1 else: result[h] = 0 hair_styles = [[h, result[h]] for h in tags[13:18]] hair_styles.sort(key=lambda x:x[1], reverse=True) for h in tags[13:18]: if h == hair_styles[0][0]: result[h] = 1 else: result[h] = 0 eye_colors = [[h, result[h]] for h in tags[18:28]] eye_colors.sort(key=lambda x:x[1], reverse=True) for h in tags[18:28]: if h == eye_colors[0][0]: result[h] = 1 else: result[h] = 0 for h in tags[28:]: if result[h] > 0.25: result[h] = 1 else: result[h] = 0 fw.write(img_path + ',' + ','.join([str(result[t]) for t in tags]) + '\n') fw.close()复制代码这样一来,便得到了27772张二次元头像,以及每张头像对应的34个标签值
获取每张头像的4096维向量表示
illust2vec = i2v.make_i2v_with_chainer("illust2vec_ver200.caffemodel")img_all = []vec_all = []for x in tqdm(range(len(images))): img_path = images[x] image = imread(img_path) vector = illust2vec.extract_feature([image])[0] img_all.append(image / 255.) vec_all.append(vector)img_all = np.array(img_all)vec_all = np.array(vec_all)复制代码随机选择2000张头像,进行tSNE降维可视化
from sklearn.manifold import TSNEfrom imageio import imsavedata_index = np.arange(img_all.shape[0])np.random.shuffle(data_index)data_index = data_index[:2000]tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)two_d_vectors = tsne.fit_transform(vec_all[data_index, :])puzzles = np.ones((6400, 6400, 3))xmin = np.min(two_d_vectors[:, 0])xmax = np.max(two_d_vectors[:, 0])ymin = np.min(two_d_vectors[:, 1])ymax = np.max(two_d_vectors[:, 1])for i, vector in enumerate(two_d_vectors): x, y = two_d_vectors[i, :] x = int((x - xmin) / (xmax - xmin) * (6400 - 128) + 64) y = int((y - ymin) / (ymax - ymin) * (6400 - 128) + 64) puzzles[y - 64: y + 64, x - 64: x + 64, :] = img_all[data_index]imsave('二次元头像降维可视化.png', puzzles)复制代码可视化结果如下,相似的头像确实被聚到了一起