つまりなにしたの?
前回あまりにも、残念な結果だったヒストグラム比較。
RGBでのヒストグラムを連結して比較したものから、HSV色空間でのヒストグラム比較に変更してみた。
今更OpenCVのドキュメントを読んでこっちが正攻法っぽいのでやってみることにした。
参考: OpenCV: Histogram Comparison
あと評価の仕方がよくわからないので結果に関しては感覚的なことしか言えないけど、やや改善したように見える。
前回の話
ensekitt.hatenablog.com
カラーの傾向とかもあまりなく、同じ写真同士が近くにある程度の能力
おおまかな手順
- ベースになるイメージを読み込む
- ベースになるイメージをHSV色空間でヒストグラム化する #ここと
- ヒストグラムを正規化する #ここが変わった
- フォルダ内の画像リストを作成する
- すべての画像についてベースとの近さをパラメータ化したリストを作成する
- パラメータでリストをソートする
- ソート済のリストをもとに新しいフォルダに採番済の名前でコピーする
https://docs.opencv.org/3.4.2/d8/dc8/tutorial_histogram_comparison.html
環境
% python --version Python 3.6.4 % pip freeze opencv-python==3.4.0.12 matplotlib==2.1.2 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 # 画像を読み込んでベクトル化する関数 h_bins = 50 s_bins = 60 histSize = [h_bins, s_bins] h_ranges = [0, 180] s_ranges = [0, 256] ranges = h_ranges + s_ranges # concat lists def img2hist(filename): img = cv2.imread(filename) # ベースになるイメージをHSV色空間でヒストグラム化する img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hist = cv2.calcHist([img], [0,1], None, histSize, ranges, accumulate=False) # ヒストグラムを正規化する cv2.normalize(hist, hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX) return hist # ベースになるイメージを読み込む base_path = "base.jpg" # ベースになるイメージをヒストグラム化する basehist = img2hist(base_path) # フォルダ内の画像リストを作成する image_path = "images/*.jpg" path_list = glob.glob(image_path) # すべての画像についてベースとの近さをパラメータ化したリストを作成する image_list = [] for path in path_list: targethist = img2hist(path) simi = cv2.compareHist(basehist, targethist, 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)
やってみた結果