今回は前回から継続して投稿してきた画像認識と打って変わって映像認識を機械学習を通じて皆様にご紹介させていただこうと思います。
画像認識もままならないのに動画認識をいきなり実践的にコーディングをしても問題ないのかという不安の声が聞こえるような気もしますが画像認識同様映像認識にもpython環境で用意されたパッケージがあり、簡単に行うことが可能です。そもそも映像というとは画像をコマ送りにしただけなのでその画像一つ一つに画像認識を行なったものが映像認識技術になると考えるとそこまでレベルの高いことを行なっているわけではなさそうですね。
前回の記事をまだご覧になっていない方はこちらからぜひ一読ください。
動画解析 – 動画から熱帯魚が映った場面を検出しよう
画像の次は動画を扱ってみましょう。動画といっても連続する静止画ですので 厳密には画像処理と似ています。ここでは、OpenCV でWeb カメラを扱う方法を確認してみましょう。
動画の解析について
OpenCV を使えば、Web カメラからの入力も手軽に行うことができます。そのため、監視力メラを作ったり、道路を横切る車の数を数えたりと、リアルタイムに画像処理を行うことができます。本節のプログラムを実行する場合は、PCの内蔵カメラ(あるいは USB 接続のカメラ)を接続したPCで実行する必要があります。OpenCV は Raspberry Pi などIOT 機器にもインストール可能で、それらの機器で動画を連続キャプチャー可能なので、ぜひ実機で実行してみてください。
Web カメラの画像をリアルタイムに表示しよう
以下のプログラムは、OpenCV でカメラの映像を取得し、PCのディスプレイに表示するだけのサンプルで、Jupyter Notebook ではなく、コマンドラインから実行します。なお、PCの Webカメラにアクセスしますので、カメラのある機器で試してください。 Raspberry Pi などの loT 機器でも動かすことができます。
import cv2
import numpy as np
# Web カメラから入力を開始(* 1)
cv2.VideoCapture (0)
while True:
# カメラの画像を読み込む(*2)
frame = cap.read()
# 画像を縮小表示する(*3)
frame = cv2.resize(frame, (500,300)).
# ウィンドウに画像を出力(*4)
cv2.imshow(‘OpenCV Web Camera’.
# ESCか Enterキーが押されたらループを抜ける
k = cv2.waitKey (1) # 1msec 確認
if k == 27 or k == 13: break
cap.release()# カメラを解放
cv2.destroyAllWindows () # ウィンドウを破棄
コマンドラインで、プログラムのあるディレクトリーを開き、以下のコマンドを実行します。
python camera-sample.py
すると、ウィンドウが起動し、そこに Web カメラの画像がリアルタイムに映し出されます。ESCキーかEnter キーを押すとプログラムを終了します。プログラムを確認してみます。(※1)の部分では、VideoCapture(0) で標準のWeb カメラを利用する準備をします。このプログラムでは、繰り返し画像を読み込むことで、動画をウィンドウに出力しプログラムの(※ 2)の部分で、read0 メソッドで画像を読み出します。ここでは、それほど大きな画(※4)の部分で、imshow) 関数を利用して、ウィンドウに画像を出力します。像は必要ないので、(※3)の部分で、resize() 関数を使って画像を縮小表示します。数でそのとき押されているキーを取得し、ESC か Enter キーが押されていれば、ループを終了します。
カメラ画像から赤色成分だけを表示してみよう
Web カメラから取得した画像は、これまでの画像処理と同じく、NumPy の配列形式 (ndarray)の画像データとなっています。そのため、画像をリアルタイムに解析して処理することが可能です。ここでは画像データから、青色成分と緑色成分をカットして、カメラに写った赤色の部分だけを画面に出力するようにしてみましょう。
プログラムは以下のようになります。
import cv2
import numpy as np
# Web カメラから入力を開始
cap= cv2.VideoCapture (0)
while True:
# 画像を取得
frame = cap.read()
# 画像を縮小表示
frame = cv2.resize (frame, (500,300))
# 青色と緑色の成分を0に(NumPyのインデックスを利用) (※1)
frame[:,:,0] = 0 # 青色要素を0
frame[:,:,1] = 0 # 緑色要素を0
# ウィンドウに画像を出力
cv2. imshow (‘RED Camera’, frame)
# Enter キーが押されたらループを抜ける
if cv2.waitKey(1)== 13: break
cap.release()# カメラを解放
Cv2.destroyA11Windows()# ウィンドウを破棄
コマンドラインから実行すると、この紙面ではわかりませんが、真っ赤なカメラ画像が表示されます。Enter キーを押すとプログラムを終了します。プログラムのポイントは、(※1)の部分です。NumPy のインデックス機能を利用して、すべての画素で青色要素と緑色要素の成分を0に設定します。これにより、RGB のR(赤色)の値のみ画像に表示しています。こうした NumPy のインデックスを利用した画素の操作は高速です。
HSV色空間を利用した色の検出
しかし、これだと赤い部分だけ表示しているという感じはあまりありません。そこで、赤色の部分だけを抽出して表示するようにしてみましょう。そのためには、HSV色空間を使うと良いでしょう。HSV色中間では、色相 (hue)·彩度(saturation) ·明度 (value brightness) の3つのパラメーターで色を表現オる方式です。RGB 色空間は、赤緑青の原色による色の組み合わせで色を表現しますので、色の変化がイメージしにくいものです。しかしHSV 色空間では、彩度や明度を用いて色を調整するので、感覚的に色を指定できます。色相は360度の円形で、右回りに赤→緑→青→赤のように色の円で表現します。
以下のプログラムは、色相で赤色っぽい部分を取り出して白色で表示するプログラムです。
import cv2
import numpy as np
# Web カメラから入力を開始
cap=cv2. VideoCapture (0)
while True:
# 画像を取得して縮小する
frame =cap.read()
frame = cv2.resize(frame, (500,300))
# 色空間をHSV に変換(*1)
hsv = cv2.cvtColor (frame, cv2.COLOR_BGR2HSV_FULL)
# HSVを分割する(*2)
h = hsv[:, :, 0]
s = hsv[:, :, 1]
v = hsv[:
# 赤色っぽい色を持つ画素だけを抽出(*3)
img= np.zeros (h.shape, dtype=np.uint8)
img [((h < 50) (h > 200)) & (s > 100)]
# ウィンドウに画像を出力(*4)
cv2. imshow (‘RED Camera’, img)
if cv2.waitKey (1)== 13: break
cap.release()# カメラを解放
cv2.destroyAllWindows () # ウィンドを廃棄
プログラムをコマンドラインから実行すると、以下のように表示されます。プログラムを見てみましょう。(※1)の部分で色空間をHSVに変換し、(※2)の部分でh/s/vの各要素に分割します。そして、(※3) の部分で赤っぽい色を持つ画素を白 (255) で塗りつぶします。そして、塗りつぶした画像を(※4)でウィンドウに表示します。プログラムの(※3)の部分で、パラメーターを調整することで、特定の色を持つ領域を選別できます。このように、カメラ画像をリアルタイムに解析して、出力結果を自由にカスタマイズすることもできます。ヒントとしては、前節の輪郭抽出のテクニックと組み合わせるなら、赤っぽい部分だけを輪郭抽出することが可能となります。画面に動きがあった部分を検出じよう動画は複数画像の連続です。そのため、各フレームの差分を調べることで、画面に起きた変化を検出できます。画像の差分を調べるには、cv2.absdiff) 関数を利用します。プログラムを見てみましょう。
import cv2
cap=cv2.VideoCapture (0)
img_last=None # 前回の画像を記憶する変数 (※1)
green=(0, 255, 0)
while True:
# 画像を取得
_,frame =cap.read ()
frame =cv2.resize (frame, (500, 300))
# 白黒画像に変換(*2)
gray=cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (9, 9), 0)
img_b = cv2. threshold(gray, 100, 255, cv2.THRESH_BINARY) [1]
# 差分を確認する
if img_last is None:
img last=img_b
continue
frame_diff =cv2. absdiff(img_last, img_b) # 画像ごとの差分を調べる(* 3)
cnts = cv2.findContours (frame_diff,
cv2.RETR_EXTERNAL,
cv2. CHAIN_APPROX_SIMPLE) [0]
# 差分があった点を画面に描く(* 4)
for pt in cnts:
х, у, w, h =cv2.boundingRect (pt)
if w < 30: continue # 小さな変更点は無視
cv2.rectangle (frame, (x, y), (x+w, y+h), green, 2)
# 今回のフレームを保存(*5)
img_last= imag_b
# 画面に表示
cv2.imshow(“Diff Camera”, frame)
cv2. imshow(“diff data”, frame_diff)
if cv2.waitKey (1) == 13: break
cap.release ()
cv2. destroyAllWindows ()
コマンドラインから実行すると、以下のように動きのあった部分を検出し、緑色の四角で囲って表示します。以下の画像は、カメラにぬいぐるみを写し、左右に動かしたところです。
プログラムを確認してみましょう。プログラムの(※1)の部分で変数 img_last を初期化しています。この変数に1つ前の画像を記録しておきます。(※2)の部分では、比較をしやすくするために白黒画像に変換しておきます。その際、グレースケールに変換して、ぼかし処理をかけた上で白黒二値化しておきます。(※3)の部分では、Cv2.absdiff() 関数で画像ごとの差分を調べます。;Aの部分では、cv2.findContours0 関数で輪郭抽出した結果に緑色の長方形を描画します。そして、最後(※5) の部分で、変数 img_last に画像を記録します。以下は、Cv2.absdiff) 関数の結果を表示したものですが、動きがあった部分が濃い白い線で表示されるのがわかります。
また、監視カメラのような用途では、画面に大きな動きがあったときに、画像を保存し、そこに何が映っているかを判定できます。顔検出などと組み合わせれば、訪問者の顔を検出して保存しておいて、機械学習で誰が来たのか判定するという用途にも使えるでしょう。
動画ファイルの書き出し
OpenCVで入力した画像を連続して書き込むことで、動画ファイルを作成することが可能です。以下は、Web カメラで入力した動画を記録するプログラムです。
import cv2
import numpy as np
# カメラからの入力を開始
cap=cv2.VideoCapture (0)
# 動画書き出し用のオブジェクトを生成
fmt = cv2.VideoWriter_fourcc(‘m’,’p’,’4′,’v’)
fps= 20.0
size = (640, 360)
writer =cv2. VideoWriter(‘test.m4v’, fmt, fps, size) #(*1)
while True:
_,frame =cap.read()#動画を入力
# 画像を縮小
frame = cv2.resize (frame, size)
# 画像を出力(*2)
writer.write(frame)
# ウィンドウ上にも表示
cv2.imshow (‘frame’, frame)
# Enter キーが押されたらループを抜ける
if cv2.waitKey (1)== 13: break
writer.release ()
cap.release ()
cv2.destroyAllWindows () # ウィンドを破棄
コマンドラインからプログラムを実行すると記録が開始されます。そして、Enter キーを押すと録画を停止し、プログラムが終了します。
プログラムを確認してみましょう。プログラムの(※ 1)では、cv2VideoWriter で動画書き出し用のオブジェクトを得ます。第1引数にはファイル名、第2引数のfmt には動画の書き出しフォーマットを指定します。ここでは、MPEG-4 Video を表す4文字の動画コーデック (mp4v)を1文字ずつ指定しています。第3引数は FPS(1 秒間のフレーム数)を、第4引数は動画の画面サイズを指定します。そして、プログラムの(※ 2)の部分にあるように、繰り返しwite) メソッドを使って書き出す画像を指定します。
動画から熱帯魚が映った場面を抽出しよう
そこまでの部分で、動画の基本的な処理方法を紹介しました。応用編として、海のなかを撮影した動画の中から、熱帯魚が映っている場面を抽出するプログラムを作ってみましょう。本書のサンプルプログラムに「fish.mp4」という動画ファイルがあるので、これを使ってみましょう。
熱帯魚は右へ左へと動き回るので、先ほど試したように、cv2.absdiff) 関数を使って前のフレームとの差分を取れば、動いている部分、つまり、熱帯魚の可能性がある部分を抽出できます。以下のプログラムを実行すると、動画の各フレームを調べ、動きがあった部分を<exfish> というディレクトリーに抽出してJPEG画像として保存します
import cv2, os
img last=none#前回の画像
no = 0 # 画像の枚数
save_dir = “./exfish” # 保存ディレクトリー名
os.mkdir(save_dir) # ディレクトリーを作成
# 動画ファイルから入力を開始(* 1)
cap= cv2.VideоСapture (“fish.mp4”)
while True:
# 画像を取得
is_ok, frame = cap.read()
if not is_ok: break
frame = cv2.resize (frame, (640, 360))
# 白黒画像に変換(*2)
gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur (gray, (15, 15), 0)
img_b=cv2. threshold(gray, 127, 255, cv2.THRESH_BINARY) [1]
# 差分を確認する
if not img_last is None:
frame_diff= cv2.adsdiff(img_last,img_b)
cnts=cv2.findContours (frame_diff,
cv2. RETR_EXTERNAL,
cv2. CHAIN_APPROX_SIMPLE) [0]
# 差分があった領域をファイルに出力(*4)
for pt in cnts:
x, y, w, h = cv2.boundingRect (pt)
if w < 100 or w > 500: continue # ノイズを除去
# 抽出した領域を画像として保存
imgex= frame [y:y+h, x:x+w]
outfile = save_dir + “/” + str(no) + “.jpg”
cv2.imwrite(outfile, imgex)
no += 1
img_last=img_b
cap.release ()
print (“ok”)
抽出した画像は、以下のようになります。狙い通り、熱帯魚の画像をたくさん抽出します。ただし、抽出した画像を見ると、熱帯魚以外のたくさんの画像を抽出してしまっています。
熱帝魚以外何が映っているのか確認すると、海のなかを撮影した動画なので、魚以外にも水泡や海底などが映っていました。
抽出結果はさておき、プログラムを確認してみましょう。プログラムの(※1)の部分では、動画ファイル「ish.mp4」から入力を行います。OpenCV では、Web カメラだけではなく、動画ファイルから読み込んだ画像を取り出すことが可能です。これまで、VideoCapture) の引数には0を与えてきましたが、ここに動画ファイルのファイル名を指定することで、カメラではなく動画ファイルから入力を得ることができます。続いて(※2)の部分では、画像を白黒画像に変換します。(※3)の部分では、前回のフレームとの差分を抽出します。(※4)の部分で、変化のあった領域を JPEG 画像として保存します。
機械学習で動画に熱帯魚が映っているベストな場面を見つけよう
関係ない画像を1から10まで手作業で分けるのはたいへんです。そこで、先ほど動画から取り出した画像で、熱帯魚が映っていたものと映っていないものを300枚ほど手動で振り分けておいて、機械学習にかけてみましょう。これによって、動画にたくさん熱帯魚が映っている1枚、つまり、ベストな画像を取り出すことができます。
熱帯魚を学習させよう
まずは、学習用の画像を準備しましょう。熱帯魚の画像を150枚と、映っていなかった画像を150枚をディレクトリーに振り分けましょう。先ほど、動画から取り出した画像が<exfish> ディレクトリーに保存されています。この画像を振り分けて、魚が映っている画像を<fish> ディレクトリーに、魚が映っていない画像を<nofish> ディレクトリーに保存しましょう。
保存したら、以下のプログラムを実行して、画像を学習させます。Jupyter Notebook で実行する場合は、Jupyter の実行ディレクトリーに、fish/nofish ディレクトリーを配置してください。
import cv2
import os, glob, pickle
from sklearn.model_selection import train_test_split
from sklearn import datasets, metrics
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 画像の学習サイズやパスを指定
image_size =(64, 32)
path = os.path.dirname (os.path.abspath(__file__))
path_fish = path + ‘/fish’
path_nofish=path + ‘/nofish’
x =[]#画像データ
y= []# ラベルデータ
# 画像データを読み込んで配列に追加(* 1)
def read_dir (path, label):
files =glob.glob(path + “/*.jpg”)
for f in files:
img= cv2.imread (f)
img= cv2.resize (img, image_size)
img_data = img.reshape (-1, ) # 一次元に展開
x.append (img_data)
y.append (label)
# 画像データを読み込む
read_dir(path_nofish, 0)
read_dir (path_fish, 1)
# データを学習用とテスト用に分割する(*2)
X_train, x test, y_train, y_test =
train_test_split (x, y, test_size=0.2)
# データを学習(*3)
clf = RandomForestClassifier()
clf.fit (x_train, y_train)
# 精度の確認(*4)
y-pred = clf.predict (x_test)
print(accuracy_score(y_test, y_pred))
# データを保存(*5)
with open(“fish.pkl”, “wb”) as fp:
pickle.dump(clf, fp)
プログラムを実行してみましょう。すると、魚の映っている画像と、映っていない画像を学習」分類精度を表示します。また、学習済みデータを「fish.pkl」という名前で保存します。以下は、コマンドラインから実行したところですが、0.93 (93%)と比較的良い数値を得ることができました。
python fish_train.py
0.931034482759
プログラムを確認してみましょう。プログラムの(※1)では画像データを読み込んで配列に追加する関数read_dir0 を定義します。ここでは、指定されたディレクトリーにあるJPEG 画像をデータに追加します。画像データを読み込み、画像をリサイズして、リスト型の変数xとyに追加します。機械学習では、学習するデータは同じサイズである必要があります。そのため、今回学習対象となる画像データはさまざまなサイズですが、すべてを64 × 32 ピクセルにリサイズしてからデータに追加します。ここで、正方形にせず64 × 32 ビピクセルとしたのは、画像データを確認し、横長の画像が多かったためです。プログラムの(※2) では、データをシャッフルして学習用とテスト用に分割します。(※3)ではデータを学習します。ここでは、学習アルゴリズムにランダムフォレストを利用しました。(※4)では、学習データの精度を確認し表示します。(※5)の部分では、学習済みデータを「fish.pkl」という名前で保存します。
動画を解析しよう
それでは、実際の動画ファイルから熱帯魚のたくさん映った場面を抽出するプログラムを作ってみださい。プログラムが魚と判定した領域に枠を表示します。ましょう。このプログラムは、動画ウィンドウを表示しますので、コマンドラインから実行してみてく
import cv2, os , copy, pickle
# 学習済みデータを取り出す
with open (“fish.pkl”, “rb”) as fp:
clf =pickle.load(fp)
output_dir = “./bestshot”
img last =None # 前回の画像
fish_th = 3 # 画像を出力するかどうかのしきい値
count=0
frame count = 0
if not os.path.isdir(output_dir): os.mkdir(output_dir)
# 動画ファイルから入力を開始(* 1)
cv2.VideoCapture(“fish.mp4”)
while True:
# 画像を取得
is_ok, frame =cap.read ()
if not is_ok: break
frame = cv2.resize(frame, (640, 360))
frame2 =copy. copy (frame)
frame_count += 1
# 前フレームと比較するために白黒に変換(*2)
grey=cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY)
gray= cv2. GaussianBlur (gray, (15, 15), 0)
gray=cv2. threshold(gray, 127, 255, cv2. THRESH_BINARY) [1]
if not img_last is None:
# 差分を得る
frame_diff = cv2. absdiff(img_last, img_b)
cnts = cv2.findContours(frame_diff,
cv2. RETR_EXTERNAL,
cv2. CHAIN_APPROX_SIMPLE) [0]
# 差分領域に魚が映っているか調べる
fish_count = 0
for pt in cnts:
х, у, w, h = cv2.boundingRect(pt)
if w < 100 or w > 500: continue # ノイズを除去
# 抽出した領域に魚が映っているか確認(*3)
Imgex= frame [y:y+h, x:x+w]
Imagex = cv2.resize (imgex, (64, 32))
image_data =imagex.reshape (-1, )
pred_y = clf.predict([image_data])
if pred_y [0]== 1:
fish_count += 1
cv2.rectangle (frame2, (x, y), (x+w, y+h), (0,255,0), 2)
# 魚が映っているか?(*5)
if fish_count > fish_th:
fname = output_dir + “/fish” + str(count) + “.jpg”
cv2. imwrite(fname, frame)
count += 1
cv2.imshow(‘FISH!’, frame2)
if cv2.waitKey(1)== 13: break
cap.release ()
cv2.destroyAllWindows ()
print(“ok”, count, “/”, frame_count)
プログラムを実行すると<bestshot> というディレクトリーが作成され、そこに熱帯魚がたくさん映った場面が保存されます。実行してみるとわかりますが、場面によっては熱帯魚と海底の岩を誤判定するものもあります。しかし、ある程度は熱帯魚を判定して、取り出せていると感じるのではないでしょうか。サンプルとして用意した動画は、1分ほどの短い動画ですが、画像枚数にすると1990枚にもなります。もし、これか30分にもおよぶ動画であれば、6万枚近い画像を確認しなければなりません。ですから、機械学習を利用して、魚がたくさん映っている画像を自動で判定できれば、画像を目視するという労力を大きく削減できます。
さて、プログラムを確認してみましょう。プログラムの(※1)の部分では、動画ファイルから入力(※2)以降の部分では、前回のフレームと今回のフレームを比較するための処理を行います。詳しくは、1つ前のプログラムの解説を確認してください。(※3)の部分では、差分領域を抽出し、1つずつの領域に対して、熱帯魚が映っているかどうかを機械学習で判定します。魚が映っていたと判定されると、その領域に緑色で長方形を描画します。(※4)の部分では、画像データを与えて、魚が映っているかどうかを判定します。そして、(※5)の部分で、魚がしきい値(3匹)以上映り込んでいたと判定されると、ディレクトリーを得るように指定します。<bestshot> に画像を保存します。
改良のヒント
ここでは、海の中の動画に対して、熱帯魚が映っているかどうかを判定してみました。熱帯魚は動き回るため、動画の差分を確認する方法で領域を抽出し、その上でさらに機械学習を適用して、魚が映っているかどうかを調べました。本節では差分で領域を抽出しましたが、人の顔だったり、特定の色を持つ物体など特徴があれば、差分を出す必要はないので、フレームそのものに対して、抽出処理を行うこともできるでしょう。
応用のヒント
保存した動画ではなく、Web カメラでもリアルタイムに処理できるので、監視カメラや工場ラインの監視など、さまざまな場面で応用できるでしょう。
column
OpenCV と NumPyについて
OpenCV で画像を読み込む関数 imread() では、読み込んだ画像データは、数値演算ライブラリー INumPy」の配列形式 (ndarray 型)となります。改めて紹介するまでもなく、NumPy というのは、強力な数値計算ライブラリーです。NumPyを使えば、多次元の配列を手軽に操作できます。こらに、OpenCVはさまざまなプログラミング言語で利用できるので、NumPy と一緒に使えば強力なOpenCV の機能を使えるだけでなく、NumPy による強力な行列演算機能も使うことができるのです。まさに、鬼に金棒です。そこで、OpenCV と NumPy を上手に連携させて使う方法を、改めてまとめてみます。
-
読み込んだ画像は NumPy で操作可能
本文中でも紹介しましたが、OpenCVのimread0 関数で画像データを読み込むと、imread0 関数の戻り値は numpy.ndarray 型となります。Jupyter Notebook で試してみましょう。
import cv2
img = cv2.imread (“test.png”)
print(type (img))
プログラムを実行すると、以下のように表示されます。つまり、imread0関数で読み込んだ画像は、NumPy の各種機能を利用してフィルター処理できます。
<class ‘numpy.ndarray’>
-
ネガボジ反転してみよう
NumPy によるフィルター処理の例として、画像をネガポジ反転するプログラムを作ってみましょう。OpenCV+Python の威力を実感できます。
import matplotlib.pyplot as plt
import cv2
# 画像を読み込む
img =clf.predict([image_data])
# ネガポジ反転
img= 255 – img
# 画像を表示
plt.imshow (cv2.cvtColor (img, cv2.COLOR_BGR2RGB))
plt.show ()
以下がプログラムを実行したところです。ネガポジ反転する処理は、なんと1行で「img= 255img」と書くだけです。と言うのも、各ピクセル値は青緑赤で表されますが、各要素が0から255 までの数値で表されます。NumPyを使えばそのすべての要素に対して、演算を行うことかできるのです。
機械学習を実践する際に、色情報を落としてグレースケールで処理したいという場合もよくあります。画像をグレースケールに変換する場合も、cv2.cvtColor) 関数を利用します。以下のプログラムは、カラー画像をグレースケールに変換して表示します。
import matplotlib.pyplot as plt
import cv2
# 画像を読み込む
img = cv2.imread (“test.jpg”)
# 色空間をグレースケールに変換
img
cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
# 画像を表示
plt.imshow (img, cmap=”gray”)
plt.axis(“off”)
plt.show ()
色空間の変換を行う cv2.cvtColor0 関数の第2引数には、以下のパラメーターを指定できますなお、OpenCV は150種類以上の色空間の変換を用意しています。以下に、よく使う定数を表にまとめてみました。
なお、すべての定数を列挙したいときは、Jupyter Notebook で、以下のプログラムを実行すれば全定数を列挙して表示できます。
import cv2
[i for i in dir (cv2) if i.startswith(‘COLOR_’) ]
column
画像の反転回転処理について
OpenCV にはさまざまなフィルターが用意されています。フィルターをうまく使えば、効率的に画像処理を行うことができます。また、画像の反転や回転も可能です。ここでは機械学習で必要になりそうな反転·回転の方法についてまとめてみました。後ほど詳しく紹介しますが、機械学習は学習データを割り増しすることで、精度を高めることができるので、これらの処理はとくに重要になります。
-
左右反転と上下反転
「cv2.flip0」を利用すると画像の左右反転、上下反転を行うことができます。
import matplotlib.pyplot as plt
import cv2
# 画像を読み込む
img= cv2.imread (“test.jpg”)
# 元画像を左側に表示
plt.subplot (1, 2, 1)
plt. imshow(cv2.cvtColor (img, cv2.COLOR_BGR2RGB))
# 画像を左右反転
plt.subplot (1, 2, 2)
img2= cv2.flip(img, 1)
plt.imshow(cv2.cvtColor (img2, cv2.COLOR_BGR2RGB))
plt.show ()
[書式]画像の反転
Cv2.fip(画像データ,反転方向)
反転方向に0を与えると上下反転、1を与えると左右反転となります。以下の画像は、反転方向に0を与えた場合の実行例です。
この節のまとめ
・OpenCV を使うと、Web カメラからの画像をリアルタイムに処理できる
・動画ファイルも Web カメラとほぼ同じ手順で処理できる
・動画ではフレームの差分を確認することで、どこに動きがあったかを検出できる
・機械学習を利用して、動画から任意の場面を検出できる