つまりなにしたの?
いっぱい写真があると画像の近さで並び替えたくなるので、今回は安易にヒストグラムだけを比較して画像の名前を採番しなおしてみた。
ただ、ヒストグラムだけだとやっぱり空間情報(どのへんが青いとか)が失われるのであまり綺麗にできなかった。
前回の話
ensekitt.hatenablog.com
ここでは相関を使って並び替えていたし、今回発生する問題はこの段階でわかっていたけど、切りが悪いのでやるところまでやった。
おおまかな手順
- ベースになるイメージを読み込む
- ベースになるイメージをベクトル化する
- フォルダ内の画像リストを作成する
- すべての画像についてベースとの近さをパラメータ化したリストを作成する
- パラメータでリストをソートする
- ソート済のリストをもとに新しいフォルダに採番済の名前でコピーする
環境
% python --version Python 3.6.4 % pip freeze opencv-python==3.4.0.12 numpy==1.14.1
フォルダ
. ├── base.jpg ├── img_sort.py ├── images └── results # 実行するとできる
コード
import glob import cv2 import numpy as np import matplotlib.pyplot as plt import os import shutil # 画像を読み込んでベクトル化する関数 def img2histvec(filename): img = cv2.imread(filename) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) histrgb = [] color = ['r','g','b'] for i,col in enumerate(color): histrgb.append(cv2.calcHist([img],[i],None,[256],[0,256])) histarray = np.array(histrgb) histvec = histarray.reshape(histarray.shape[0]*histarray.shape[1], 1) return histvec # ベースになるイメージを読み込む base_path = "base.jpg" # ベースになるイメージをベクトル化する basevec = img2histvec(base_path) # フォルダ内の画像リストを作成する image_path = "images/*.jpg" path_list = glob.glob(image_path) # すべての画像についてベースとの近さをパラメータ化したリストを作成する image_list = [] for path in path_list: targetvec = img2histvec(path) simi = cv2.compareHist(basevec, targetvec, 3) #3はBhattacharyya distanceのこと image_list.append((simi, path)) # パラメータでリストをソートする sorted_list = sorted(image_list, key=lambda tgt: tgt[0], reverse=True) # ソート済のリストをもとに新しいフォルダに採番済の名前でコピーする result_dir = "results" if not os.path.exists(result_dir): os.mkdir(result_dir) for i, info in enumerate(sorted_list): new_path = os.path.join(result_dir, "{0:08d}.jpg".format(i)) temp_path = info[1] shutil.copyfile(temp_path, new_path)