はじめに
機械学習で人物検出などを実装する時のノウハウとして、以下のようなものがあるかと思います。
- できるだけ正面で
- できるだけ均一に照らす
2つ目の明るさについては、ヒストグラム平坦化という画像処理をすることによって改善することができるため、その手法を解説します。
なお、こちらの記事は以下のリンクをなぞっただけのものとなります。必要であれば参考にしてください。。
ヒストグラムとは
度数分布(連続する何かを区切ったものに対する個数のバラつき具合)を表現するときに使うグラフのことです。
画像のヒストグラムというと、画素値の分布を表したグラフのことです。
ヒストグラム平坦化とは
ヒストグラム平坦化とは、下の画像のようにヒストグラムが明るい領域に集中している画素値を全範囲に分布させるための変換のことです。
適用的ヒストグラム平坦化(CLAHE)とは
適用的ヒストグラム平坦化とは、__小さい領域毎にヒストグラム平坦化を適用__していく処理のことです。
具体的には、OpenCVのデフォルトでは 8x8の領域毎にヒストグラム平坦化を適用 します。
どういった時に適用的ヒストグラム平坦化(CLAHE)を適用するかというと・・・
ヒストグラムに偏りが発生していない画像にヒストグラム平坦化を適用すると、明るくなりすぎたり暗くなりすぎたりして逆効果になってしまう場合があります。
やってみた
元画像
こちらの画像を元として、ヒストグラム平坦化と適用的ヒストグラム平坦化(CLAHE)を適用してみました。
ヒストグラム平坦化
顔の部分が明るくなりすぎて、顔検出する時には精度が落ちてしまいます。
これは入力画像のヒストグラムが特定の範囲に偏っていないことが原因のようです。
import numpy as np
import cv2
img = cv2.imread('original.jpg',0)
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ)) #stacking images side-by-side
cv2.imwrite('histogram.png',res)
適用的ヒストグラム平坦化(CLAHE)
上述したヒストグラム平坦化と比較すると、顔部分の明るさ具合がちょうどよく、顔検出する時にも精度が高くなります。
import numpy as np
import cv2
img = cv2.imread('original.png',0)
# create a CLAHE object (Arguments are optional).
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv2.imwrite('clahe_histogram.jpg',cl1)
まとめ
スペックの低いラズパイなどでビデオ映像などリアルタイムで処理したい場合、この処理を実装するとFPSが低くなってしまうというのが難点です。
しかし、時間帯によって明るさが変化する環境では非常に良いソリューションとなります。
使用する状況を加味して実装を検討してみてください。
誤り等があればコメントにてよろしくお願いします。
参考
- Histogram equalization