今回は大量の画像を一括で処理することを目的とします。
数枚であればプログラム数行でできます。
前提として以下のようなlabels.csvファイルとそれに対応した画像があるとします。
filename: ファイル名
width height: 画像ファイルのサイズ
class: 分類ラベル
xmin ymin xmax ymax: 画像内のどこに分類ラベルに該当する画像があるのかを示すバウンディングボックス座標
今回使うのはfilename、xmin、ymin、xmax、ymax
必要なもの
import numpy as np import csv import cv2
アノテーションファイル.csvの情報を扱いやすいように配列に入れる。
csv_data=[] with open("labels.csv","r", encoding='UTF-8') as f: reader = csv.reader(f) header = next(reader) #headerを読み飛ばす for line in f: #1行ずつ読み込む(行数分でfor) line = line.rstrip("\n").split(",") csv_data.append(line) #csv_data[]に1行ずつ追加 csv_data=np.array(csv_data,dtype="unicode") #numpy配列に変換 print(csv_data.shape) print(csv_data[:,:]) #データ、要素の2次元配列 >>(631, 8) [['01.jpg' '4032' '3024' ... '612' '1288' '1778'] ['01.jpg' '4032' '3024' ... '819' '2768' '1912'] ['02.jpg' '4032' '3024' ... '878' '2477' '1951'] ... ['49.jpg' '4032' '3024' ... '2151' '2795' '2612'] ['49.jpg' '4032' '3024' ... '607' '2043' '1101'] ['49.jpg' '4032' '3024' ... '107' '1954' '596']]
画像のディレクトリ+先ほどの配列1列目を結合した画像パスを別の配列に入れる
今回は相対パスで作業を進めます。
dir_path="./" #画像のディレクトリ img_path=[] cnt=(csv_path.shape[0]) #データ数をcntに代入 for i in range(cnt): #cnt分繰り返す img_path.append(dir_path+csv_path[i,0]) #img[]に1枚ずつ読み込み img_path=np.array(img_path) #画像パスの1次元配列 print(img_path) >>['./01.jpg' './01.jpg' './02.jpg' './02.jpg' './03.jpg' './03.jpg' './04.jpg' './04.jpg' './05.jpg' './05.jpg' './06.jpg' './06.jpg' ... './49.jpg' './49.jpg' './49.jpg' './49.jpg' './49.jpg' './49.jpg' './49.jpg']
ついでにバウンディングボックスの座標も取り出しておく
bbox=[] cnt=(csv_data.shape[0]) #データ数をcntに代入 for i in range(cnt): #データ数分繰り返す bbox.append(csv_data[i,4:]) #bbox[]にバウンディングボックスの座標を1つずつ格納 bbox=np.array(bbox,dtype="int64") print(bbox) >>[[ 125 612 1288 1778] [1668 819 2768 1912] [1413 878 2477 1951] ... [2336 2151 2795 2612] [1570 607 2043 1101] [1466 107 1954 596]]
img_pathとbboxを使って画像をトリミング後、指定フォルダに保存
cnt = (csv_data.shape[0]) for i in range(cnt): #ラベル分処理する img_array = cv2.imread(img_path[i]) #i番目の画像を読み込み dst = img_array[(bbox[i,1]):(bbox[i,3]),(bbox[i,0]):(bbox[i,2])] #i番目の座標を使ってトリミング cv2.imwrite('./coin/coin{0}.jpg'.format(i), dst) #coin[i].jpgで保存
以上のプログラムよって以下の画像から
以下の2枚の画像に分割できます。