tfrecordsを生成する

csv & txt to tfrecords

こんな感じのテキストがファイルに入っていれば使えます。
./train/小原鞠莉/3_75344a4023c221540fb87b69f7b02cab.jpg,4
ファイルの場所,ラベル

#!/usr/bin/env python

import tensorflow as tf
import sys
import os
import csv
from PIL import Image

def csvread(filename):
	record_file = filename+".tfrecords"
	writer = tf.python_io.TFRecordWriter(record_file)
	
	f = open(filename, 'r')
	reader = csv.reader(f)
	header = next(reader)
	
	img_data = []
	img_n = [0,1]
	for row in reader:
		print (row[0])
		img_n[0] = row[0]
		img_n[1] = int(row[1])
		img_data.append(img_n)
	f.close()
	to_TF(img_data,writer)
	
def to_TF(img_data,writer):
	for img_datum in img_data:
		img_file = img_datum[0]
		img_label = img_datum[1]
		
		img = Image.open(img_file)
		width, height = img.size
		
		record = tf.train.Example(features=tf.train.Features(feature={
			'label' : tf.train.Feature(int64_list=tf.train.Int64List(value=[img_label])),
			'image' : tf.train.Feature(bytes_list=tf.train.BytesList(value=[img.tobytes()])),
			'height': tf.train.Feature(int64_list=tf.train.Int64List(value=[height])),
			'width' : tf.train.Feature(int64_list=tf.train.Int64List(value=[width])),
			'depth' : tf.train.Feature(int64_list=tf.train.Int64List(value=[3])),
		}))
		writer.write(record.SerializeToString())
		
if __name__ == '__main__':
	if sys.argv[1] == "create":
		csvread("./test.txt")
		csvread("./train.txt")
		
	elif sys.argv[1] == "test":
		csvread("./test.txt")
		
	elif sys.argv[1] == "train":
		csvread("./train.txt")
		
	else:
		csvread(sys.argv[1])
	
	

txtを生成する

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import csv
from PIL import Image
import subprocess

'''
使い方

引数
result result.csvを生成
mkdir 分類用フォルダを生成
create 学習に必要なtxtを生成
test.txtを生成
train.txtを生成
'''
def result(outdir):
	if not os.path.isdir(outdir):
		sys.exit('%s is not directory' % outdir)

	f = open("result.csv","w")
	for dirpath, dirnames, filenames in os.walk(outdir):
		for dirname in dirnames:
			member_dir = os.path.join(dirpath, dirname)
			for dirpath2, dirnames2, filenames2 in os.walk(member_dir):
				if not dirpath2.endswith(dirname):
					continue
				for filename2 in filenames2:
					img_path = os.path.join(dirpath2, filename2)
					print (img_path)
					text = img_path+'\r\n'
					f.write(text)
						
	# ファイルを閉じる			
	f.close()
	print ("作成成功")
	

def output(outdir):
	if outdir.rfind("test") == 2:
		filename3 = "test.txt"
	else:
		filename3 = "train.txt"
	
	if not os.path.isdir(outdir):
		sys.exit('%s is not directory' % outdir)

	names = {
	"高海千歌": 0,
	"黒澤ダイヤ": 1,
	"国木田花丸": 2,
	"松浦果南": 3,
	"小原鞠莉": 4,
	"桜内梨子": 5,
	"黒澤ルビィ": 6,
	"津島善子": 7,
	"渡辺曜": 8,
	"高坂穂乃果": 9,
	"絢瀬絵里": 10,
	"南ことり": 11,
	"園田海未": 12,
	"矢澤にこ": 13,
	"星空凛": 14,
	"西木野真姫": 15,
	"東條希": 16,
	"小泉花陽": 17
	}

	exts = ['.PNG','.JPG','.JPEG']
	f = open(filename3,"w")
	for dirpath, dirnames, filenames in os.walk(outdir):
		for dirname in dirnames:
			if dirname in names:
				n = names[dirname]
				member_dir = os.path.join(dirpath, dirname)
				for dirpath2, dirnames2, filenames2 in os.walk(member_dir):
					if not dirpath2.endswith(dirname):
						continue
					for filename2 in filenames2:
						(fn,ext) = os.path.splitext(filename2)
						if ext.upper() in exts:
							img_path = os.path.join(dirpath2, filename2)
							print ('{0} {1}'.format(img_path, n))
							
						text = img_path + " " + str(n) +'\r\n'
						f.write(text)
						
	# ファイルを閉じる			
	f.close()
	print ("作成成功")
	
if __name__ == '__main__':
	
	if sys.argv[1] == "mkdir":
		if not os.path.isdir("test") or not os.path.isdir("train"):
			os.makedirs("test/高海千歌")
			os.makedirs("train/高海千歌")
			os.makedirs("test/黒澤ダイヤ")
			os.makedirs("train/黒澤ダイヤ")
			os.makedirs("test/国木田花丸")
			os.makedirs("train/国木田花丸")
			os.makedirs("test/松浦果南")
			os.makedirs("train/松浦果南")
			os.makedirs("test/小原鞠莉")
			os.makedirs("train/小原鞠莉")
			os.makedirs("test/桜内梨子")
			os.makedirs("train/桜内梨子")
			os.makedirs("test/黒澤ルビィ")
			os.makedirs("train/黒澤ルビィ")
			os.makedirs("test/津島善子")
			os.makedirs("train/津島善子")
			os.makedirs("test/渡辺曜")
			os.makedirs("train/渡辺曜")
			os.makedirs("test/高坂穂乃果")
			os.makedirs("train/高坂穂乃果")
			os.makedirs("test/絢瀬絵里")
			os.makedirs("train/絢瀬絵里")
			os.makedirs("test/南ことり")
			os.makedirs("train/南ことり")
			os.makedirs("test/園田海未")
			os.makedirs("train/園田海未")
			os.makedirs("test/矢澤にこ")
			os.makedirs("train/矢澤にこ")
			os.makedirs("test/星空凛")
			os.makedirs("train/星空凛")
			os.makedirs("test/西木野真姫")
			os.makedirs("train/西木野真姫")
			os.makedirs("test/東條希")
			os.makedirs("train/東條希")
			os.makedirs("test/小泉花陽")
			os.makedirs("train/小泉花陽")
			print ("作成成功")
		else:
			print ("ファイルが存在するので削除してください")
			
	elif sys.argv[1] == "create":
		output("./test")
		output("./train")
		
	elif sys.argv[1] == "test":
		output("./test")
		
	elif sys.argv[1] == "train":
		output("./train")
	elif sys.argv[1] == "result":
		result("./img")
	else:
		print ("error")

顔認識と切り出し

必要なもの
lbpcascade_animeface.xml

ファイル名はdetect.pyで作りました。

# -*- coding:utf-8 -*-
import cv2
import sys
import os
import csv
from PIL import Image

def detect(filename, cascade_file = "lbpcascade_animeface.xml"):
	if not os.path.isfile(cascade_file):
		raise RuntimeError("%s: not found" % cascade_file)
	try:
		#ファイル読み込み
		image = cv2.imread(filename)
		#グレースケール変換
		gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
		gray = cv2.equalizeHist(gray)
		#カスケード分類器の特徴量を取得する
		cascade = cv2.CascadeClassifier(cascade_file)
		
		#物体認識(顔認識)の実行
		faces = cascade.detectMultiScale(gray,
										 # detector options
										 scaleFactor = 1.1,
										 minNeighbors = 5,
										 minSize = (24, 24))
		#ディレクトリの作成
		if len(faces) > 0:
			path = os.path.split(filename)
			name = path[0].split("/",2)
			
			dir_path = name[2]+ '_face'
			dir_path = "face/"+dir_path
			
			if not os.path.isdir('face'):
				os.mkdir('face')
			if not os.path.isdir(dir_path):
				os.mkdir(dir_path)
		i = 0;
		for rect in faces:
			#顔だけ切り出して保存
			x = rect[0]
			y = rect[1]
			width = rect[2]
			height = rect[3]
			dst = image[y:y+height, x:x+width]
			new_image_path = dir_path + '/' + str(i) +'_'+ path[1];
			size = (112,112)
			dst2 = cv2.resize(dst, size)
			cv2.imwrite(new_image_path, dst2)
			save(new_image_path)
			i += 1
		if len(faces) > 0:
			color = (255, 255, 255) #白
			for rect in faces:
				#検出した顔を囲む矩形の作成
				cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2)
			#認識結果の保存/
			if not os.path.isdir(dir_path +'/all'):
				os.mkdir(dir_path+'/all')
			new_image_path = dir_path + '/all/all_' + path[1]
			cv2.imwrite(new_image_path, image)
			save(new_image_path)
	except:
		print ('error')

def save(txt_path):
	if not txt_path.rfind(".png") == -1:
		img_path2 = txt_path.replace('.png', '.jpg')
		
	elif not txt_path.rfind(".jpeg") == -1:
		img_path2 = txt_path.replace('.jpeg', '.jpg')

	elif not txt_path.rfind(".gif") == -1:
		img_path2 = txt_path.replace('.gif', '.jpg')

	im = Image.open(txt_path)
	im.save(img_path2)
	os.remove(txt_path)
	print ("ファイル変換終了")

def csvread(filename):
	f = open(filename, 'r')
	reader = csv.reader(f)
	header = next(reader)
	
	for row in reader:
		print (row[0])
		detect(row[0])
	f.close()

def start():
	csvread("result.csv")
	print ("次は分類")

if __name__ == '__main__':

	s = sys.argv[1].rfind(".csv")
	if s == -1:
		#ファイルネーム読み込み
		detect(sys.argv[1])
		
	else:
		#CSV読み込み
		csvread(sys.argv[1])

jpg jpeg png をBingから収集するクローラー

ラブライブ、ラブライブサンシャインの画像を集めることができます
ファイル名はget-img.pyで作りました。

#coding: utf-8 
#Python3 version
#jpg jpeg png gifを収集するクローラー

import json
import requests
import csv
import hashlib
import urllib
import os
import detect
 
APIKEY = "@@@@@@@@@"

#0 = 全部同じフォルダ, 1 = キーワード別, 2 = キャラクター別
mode = 2 
os.remove('result.csv')

def bing_search(query):
	url = 'https://api.cognitive.microsoft.com/bing/v5.0/images/search?q='+query+'&count=150'#枚数
	# custom headers
	headers = {'Ocp-Apim-Subscription-Key': APIKEY ,'Accept': 'application/json'}
	# make GET request
	r = requests.get(url, headers=headers)
	# get JSON response
	get_image_url_list(query,r.json())
 
def get_image_url_list(query,json_data):
	image_url_list = []
	m = hashlib.md5()
	if not os.path.isdir("img"):
		os.mkdir("./img")
		
	for item in json_data['value']:
		find = True
		f = open('result.csv', 'a')
		writer = csv.writer(f,lineterminator='\n')
		
		try:
			#URL抽出
			out = urllib.parse.parse_qs(item['contentUrl'])
			out = out['r'][0]
			print (out)
			
			#ハッシュ値(ファイル名)
			m.update(out.encode('utf-8'))
			
			#この拡張子以外弾く
			find1 = out.rfind("jpeg")
			find2 = out.rfind("jpg")
			find3 = out.rfind("png")
			find4 = out.rfind("gif")
			
			#拡張子設定
			_,ext = os.path.splitext(out)
			
			if find1 != -1:
				ext = ".jpeg"
			elif find2 != -1:
				ext = ".jpg"
			elif find3 != -1:
				ext = ".png"
			elif find4 != -1:
				ext = ".gif"
			else:
				find = False
			
			#キャラクター別用に分割
			if mode == 2:
				query = query.split(" ")[0]
			
			#imgフォルダ作成
			if not os.path.isdir("./img/"+ query):
				os.mkdir("./img/"+ query)

			if mode == 0:
				#全部同じ場所
				filename = "./img/" + m.hexdigest() + ext
			else:
				#キーワード別&キャラクター別
				filename = "./img/" + query +"/" + m.hexdigest() + ext

			#ダウンロード
			urllib.request.urlretrieve(out,filename)

			if find:
				#CSVに書き出し
				m.update(out.encode('utf-8'))
				row = (filename,out)       
				writer.writerow(row)
			else:
				print ("NG:"+out)
				
			f.close()
			
		except:
			print ('エラー')

if __name__ == '__main__':
	keyword = ["かわいい","壁紙","アニメ"]
	for item in keyword:
		bing_search('高海千歌 ' + item)
		bing_search('桜内梨子 ' + item)
		bing_search('渡辺曜 ' + item)
		bing_search('松浦果南 ' + item)
		bing_search('黒澤ダイヤ ' + item)
		bing_search('小原鞠莉 ' +  item)
		bing_search('黒澤ルビィ ' +  item)
		bing_search('国木田花丸 ' + item)
		bing_search('津島善子 ' +  item)
		
		bing_search('高坂穂乃果 ' + item)
		bing_search('絢瀬絵里 ' + item)
		bing_search('南ことり ' + item)
		bing_search('園田海未 ' + item)
		bing_search('矢澤にこ ' + item)
		bing_search('星空凛 ' +  item)
		bing_search('西木野真姫 ' +  item)
		bing_search('東條希 ' + item)
		bing_search('小泉花陽 ' +  item)
	print ("Download Complete!" )
	detect.start()

画像クローラーv2

必要なのはhttps://www.microsoft.com/cognitive-services/en-us/bing-image-search-apiのアカウントのAPIKEY

sudo pip install requests

1キーワード150枚ぐらい集めてくれるよ!

#coding: utf-8 
import json
import requests
import csv
import hashlib
import urllib
import urlparse
import os

APIKEY = "*********************"



def bing_search(query):
	url = 'https://api.cognitive.microsoft.com/bing/v5.0/images/search?q='+query+'&count=150'#枚数
	# custom headers
	headers = {'Ocp-Apim-Subscription-Key': APIKEY ,'Accept': 'application/json'}
	# make GET request
	r = requests.get(url, headers=headers)
	# get JSON response
	get_image_url_list(query,r.json())

def get_image_url_list(query,json_data):
	image_url_list = []
	m = hashlib.md5()
	if not os.path.isdir("img"):
		os.mkdir("./img")

	query = query.decode('utf8')
	for item in json_data['value']:
		f = open('result.csv', 'a')
		writer = csv.writer(f,lineterminator='\n')
		#URL抽出
		try:
			URL = item['contentUrl']
			#start
			o = URL.find("&r=") +3
			#end
			p = URL.rfind("&p=DevEx")
				
			#URLデコード
			out = urllib.unquote(URL[o:p]).encode('utf8')
			s = out.rfind("?")
			if not s == -1:
				out = out[0:s]
			
			find = out.rfind("jpeg")
			find += out.rfind("jpg")
			find += out.rfind("png")
			m.update(out)
			
			if not os.path.isdir("./img/"+ query):
				os.mkdir("./img/"+ query)
			_,ext = os.path.splitext(out)
			
			#全部同じ場所
			#filename = "./img/" + m.hexdigest() + ext
			#キーワード別
			filename = "./img/" + query +"/" + m.hexdigest() + ext
			
			urllib.urlretrieve(out,filename)
			
			if find != -3:
				m.update(out)
				print out
				row = (filename.encode('utf_8'),out)
				writer.writerow(row)
			else:
				print "@@@@"+out
			f.close()
		except:
			print u'error'
		
if __name__ == '__main__':
	keyword = ["かわいい","壁紙","アニメ"]
	for item in keyword:
		bing_search('高海千歌 ' + item)
		bing_search('桜内梨子 ' + item)
		bing_search('渡辺曜 ' + item)
		bing_search('松浦果南 ' + item)
		bing_search('黒澤ダイヤ ' + item)
		bing_search('小原鞠莉 ' +  item)
		bing_search('黒澤ルビィ ' +  item)
		bing_search('国木田花丸 ' + item)
		bing_search('津島善子 ' +  item)
   	print "Download Complete!"

画像収集クローラーと顔の切り抜き

python 2.7で書き直した。
元はももくろだけどラブライブ!サンシャイン!!です
最新のbing Search API対応
https://datamarket.azure.com/dataset/bing/searchではない。
https://azure.microsoft.com/ja-jp/services/cognitive-services/search/です!!!

APIKEYにはhttps://www.microsoft.com/cognitive-services/en-us/bing-image-search-apiの My accountに表示されるものを使います。

これを実行するとresult.csvができます。
一人あたり1回で最高150枚取得できます。

bing_search(‘高海千歌 壁紙’)を変えるとなんでもいけると思います。

https://dev.cognitive.microsoft.com/docs/services/56b43f0ccf5ff8098cef3808/operations/571fab09dbe2d933e891028f/consoleでテストすることができます。

下を実行するのに必要なもの
https://raw.githubusercontent.com/nagadomi/lbpcascade_animeface/master/lbpcascade_animeface.xml
OpenCV2xのインストール

python url_fetch.py
#coding: utf-8
 
import json
import requests
import csv
import hashlib
import urllib
import urlparse
import os

if os.path.isfile('result.csv') :
    os.remove('result.csv')

APIKEY = "自分のキーを書いてください"

def bing_search(query):
    url = 'https://api.cognitive.microsoft.com/bing/v5.0/images/search?q='+query+'&count=150'
    # custom headers
    headers = {'Ocp-Apim-Subscription-Key': APIKEY ,'Accept': 'application/json'}
    # make GET request
    r = requests.get(url, headers=headers)
    # get JSON response
    get_image_url_list(query,r.json())

def get_image_url_list(query,json_data):
    image_url_list = []
    m = hashlib.md5()
	
    for item in json_data['value']:
        f = open('result.csv', 'a')
        writer = csv.writer(f,lineterminator='\n')
        #URL抽出
		URL = item['contentUrl']
		#start
		o = URL.find("&r=") +3
		#end
		p = URL.rfind("&p=DevEx")
			
		#URLデコード
		out = urllib.unquote(URL[o:p]).decode('utf8')
		s = out.rfind("?")
		if s != -1:
			out = out[0:s]
		
		find = out.rfind("jpeg")
		find += out.rfind("jpg")
		find += out.rfind("png")
		
		if find != -3:
			m.update(out)
			print out
			row = (query,out,m.hexdigest())
			writer.writerow(row)
		else:
			print "@@@@"+out
		f.close()
		
if __name__ == '__main__':
	bing_search('高海千歌 壁紙')
	bing_search('桜内梨子 壁紙')
	bing_search('渡辺曜 壁紙')
	bing_search('松浦果南 壁紙')
	bing_search('黒澤ダイヤ 壁紙')
	bing_search('小原鞠莉 壁紙')
	bing_search('黒澤ルビィ 壁紙')
	bing_search('国木田花丸 壁紙')
	bing_search('津島善子 壁紙')
	bing_search('ラブライブ!サンシャイン!! 壁紙')
	bing_search('lovelive Sunshine')
   	print "Complete!"
	os.system('ruby download.rb result.csv')
#coding: utf-8
require 'csv'
require 'net/http'
require 'digest/md5'
require 'openssl'
require 'time'
require 'fileutils'

DIST_DIR="imgs.#{Time.now.to_i}"
OUT_CSV_PATH="download_imgs.#{Time.now.to_i}.csv"

unless File.exist?(DIST_DIR)
  puts "mkdir #{DIST_DIR}"
  Dir.mkdir(DIST_DIR)
end

def fetch(keyword, url)
  puts uri = URI(url)
  filename = uri.path.split('/').last
  ext = filename.split('.').last

  req = Net::HTTP::Get.new(uri.request_uri)
  nhttp = Net::HTTP.new(uri.host, uri.port)
  nhttp.use_ssl = uri.scheme == 'https'
  nhttp.verify_mode=OpenSSL::SSL::VERIFY_NONE

  res = nhttp.start() do |http|
    http.request(req)
  end

  md5 = Digest::MD5.hexdigest(res.body)
  #keywordでフォルダ分けしたいとき用
  #FileUtils.mkdir_p("#{DIST_DIR}/#{keyword}")
  #puts dist_path = "#{DIST_DIR}/#{keyword}/#{md5}.#{ext}"
  
  puts dist_path = "#{DIST_DIR}/#{md5}.#{ext}"
  File.open(dist_path, 'w') do |file|
    file.write(res.body)
  end

  dist_path
end

out_csv = []

CSV.foreach(ARGV[0]) do |row|
  keyword = row[0]
  url = row[1]

  begin
    dist_path = fetch(keyword, url)
    out_csv << [keyword + "," +url + "," +dist_path+"\n"]
  rescue => e
    puts e.message
  end
end

puts "write csv"

File.open(OUT_CSV_PATH, 'w') do |file|
  out_csv.each do |row|
    file.write(row.join(','))
  end
end
system('python detect.py '+ OUT_CSV_PATH)
## -*- coding:utf-8 -*-
import cv2
import sys
import os
import csv

def detect(filename, cascade_file = "lbpcascade_animeface.xml"):
    if not os.path.isfile(cascade_file):
        raise RuntimeError("%s: not found" % cascade_file)
    try:
		#ファイル読み込み
		image = cv2.imread(filename)
		#グレースケール変換
		gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
		gray = cv2.equalizeHist(gray)
		#カスケード分類器の特徴量を取得する
		cascade = cv2.CascadeClassifier(cascade_file)
		
		#物体認識(顔認識)の実行
		faces = cascade.detectMultiScale(gray,
										 # detector options
										 scaleFactor = 1.1,
										 minNeighbors = 5,
										 minSize = (24, 24))
		#ディレクトリの作成
		if len(faces) > 0:
			path = os.path.split(filename)
			
			if path[0] == ".":
				dir_path = 'face'
			else:
				dir_path = path[0] + '_face'
				
			if not os.path.isdir(dir_path):
				os.mkdir(dir_path)
		i = 0;
		for rect in faces:
			#顔だけ切り出して保存
			x = rect[0]
			y = rect[1]
			width = rect[2]
			height = rect[3]
			dst = image[y:y+height, x:x+width]
			new_image_path = dir_path + '/' + str(i) +'_'+ path[1];
			cv2.imwrite(new_image_path, dst)
			i += 1
		if len(faces) > 0:
			color = (255, 255, 255) #白
			for rect in faces:
				#検出した顔を囲む矩形の作成
				cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2)
			#認識結果の保存/
			new_image_path = dir_path + '/' +'all_' + path[1]
			cv2.imwrite(new_image_path, image)
    except:
        print u'error'
        
if len(sys.argv) != 2:
    sys.stderr.write("usage: detect.py \n")
    sys.exit(-1)

def csvread(filename):
	f = open(filename, 'r')
	reader = csv.reader(f)
	header = next(reader)
	
	for row in reader:
		print row[2]
		detect("./"+row[2])
	f.close()

if __name__ == '__main__':

	s = sys.argv[1].rfind(".csv")
	if s == -1:
		#CSV読み込み
		detect(sys.argv[1])
	else:
		#ファイルネーム読み込み
		csvread(sys.argv[1])
		

参考にしたサイト
TensorFlowによるももクロメンバー顔認識(前編)