画像認識の基礎から応用まで: Pythonで学ぶ機械学習
Pythonで画像認識をする方法について、初心者向けにわかりやすく解説していきます。画像認識とは、コンピュータが画像の中に含まれるオブジェクトや特徴を自動的に検出して認識する技術です。画像認識は、機械学習や深層学習などの人工知能の分野で活用されており、自動運転、医療画像解析、セキュリティシステムなどさまざまな応用があります。
Pythonは、画像認識をするために必要なライブラリやツールが豊富に揃っているプログラミング言語です。Pythonで画像認識をするためには、以下の4つの手順を踏む必要があります。
- 画像データの入力
- 画像データの前処理
- 画像データの特徴抽出
- 画像データの分類または識別
それぞれの手順について、具体的なコード例とともに詳しく見ていきましょう。
1. 画像データの入力
まずは、画像認識の対象となる画像データをPythonで読み込む必要があります。ここでは、OpenCVというライブラリを使って画像データを読み込む方法を紹介します。OpenCVは、コンピュータビジョンや画像処理に関する様々な機能を提供するオープンソースのライブラリです。Python以外にもC++やJavaなどの言語で利用できます。
OpenCVをインストールするには、以下のコマンドを実行します。
pip install opencv-python
OpenCVをインポートするには、以下のように記述します。
import cv2
OpenCVを使って画像データを読み込むには、cv2.imreadという関数を使います。この関数は、引数として画像ファイルのパスを受け取り、戻り値としてNumPyの配列として表現された画像データを返します。例えば、以下のように記述すると、sample.jpgというファイル名の画像データを読み込むことができます。
img = cv2.imread("sample.jpg")
読み込んだ画像データは、ピクセルごとにRGB(赤・緑・青)の色情報が格納された3次元の配列です。例えば、256×256ピクセルのカラー画像であれば、256×256×3の配列として表現されます。各色情報は0から255までの整数値で表されます。例えば、赤色であれば[255, 0, 0]という値になります。
読み込んだ画像データを表示するには、Matplotlibというライブラリを使います。Matplotlibは、Pythonでグラフや図などを描画するためのライブラリです。Matplotlibをインストールするには、以下のコマンドを実行します。
pip install matplotlib
Matplotlibをインポートするには、以下のように記述します。
import matplotlib.pyplot as plt
Matplotlibを使って画像データを表示するには、plt.imshowという関数を使います。この関数は、引数としてNumPyの配列として表現された画像データを受け取り、画像として描画します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納された画像データを表示することができます。
plt.imshow(img)
plt.show()
plt.showは、描画した画像を表示するための関数です。これで、Pythonで画像データの入力と表示ができるようになりました。
2. 画像データの前処理
次に、入力した画像データに対して前処理を行う必要があります。前処理とは、画像データを解析しやすくするために行う処理のことです。前処理には、以下のようなものがあります。
- 画像のサイズ変更
- 画像の色空間の変換
- 画像のノイズ除去
- 画像の回転や反転
- 画像のトリミングや切り抜き
ここでは、OpenCVを使っていくつかの前処理の方法を紹介します。
画像のサイズ変更
画像のサイズ変更とは、画像のピクセル数を変更することです。例えば、256×256ピクセルの画像を128×128ピクセルに縮小することができます。画像のサイズ変更は、解析する際に必要な情報量を減らすためや、複数の画像を同じサイズに揃えるために行われます。
OpenCVで画像のサイズ変更を行うには、cv2.resizeという関数を使います。この関数は、第一引数としてNumPyの配列として表現された画像データを受け取り、第二引数として変更後の幅と高さをタプルで指定します。戻り値としてサイズ変更された画像データを返します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納された256×256ピクセルのカラー画像データを128×128ピクセルに縮小することができます。
img_resized = cv2.resize(img, (128, 128))
サイズ変更された画像データを表示するには、先ほどと同じようにMatplotlibを使います。
plt.imshow(img_resized)
plt.show()
これで、Pythonで画像のサイズ変更ができるようになりました。
画像の色空間の変換
画像の色空間の変換とは、画像の色情報を表現する方法を変換することです。例えば、RGB(赤・緑・青)からHSV(色相・彩度・明度)やグレースケール(白黒)などに変換することができます。色空間の変換は、特定の色情報を抽出したり、計算量を減らしたりするために行われます。
OpenCVで色空間の変換を行うには、cv2.cvtColorという関数を使います。この関数は、第一引数としてNumPyの配列として表現されたカラー画像データを受け取り、第二引数として変換後の色空間を指定します。戻り値として色空間が変換されたカラーまたはグレースケールの画像データを返します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納されたRGBのカラー画像データをHSVに変換することができます。
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
色空間が変換された画像データを表示するには、先ほどと同じようにMatplotlibを使います。ただし、カラー画像の場合は、plt.imshowの引数にcmapというパラメータを指定して、色空間を表すカラーマップを選択します。例えば、HSVの場合はcmap=”hsv”とします。
plt.imshow(img_hsv, cmap="hsv")
plt.show()
これで、Pythonで画像の色空間の変換ができるようになりました。
画像のノイズ除去
画像のノイズ除去とは、画像に含まれる不要な情報や雑音を除去することです。例えば、画像に映り込んだほこりや傷、撮影時の光の反射や影などがノイズとなります。ノイズ除去は、画像の品質を向上させたり、特徴抽出や分類などの後続の処理に影響を与えないようにするために行われます。
OpenCVで画像のノイズ除去を行うには、様々なフィルターを使うことができます。フィルターとは、画像の各ピクセルに対して何らかの演算を行って新しい値を与える処理のことです。フィルターには、以下のような種類があります。
- 平滑化フィルター:画像のピクセル値を周囲のピクセル値の平均や中央値などで置き換えることで、画像を滑らかにするフィルターです。例えば、ガウシアンフィルターやメディアンフィルターなどがあります。
- エッジ検出フィルター:画像のピクセル値の勾配や方向などを計算することで、画像のエッジ(境界線)や輪郭を検出するフィルターです。例えば、ソーベルフィルターやキャニーフィルターなどがあります。
- モルフォロジー変換フィルター:画像の形状や構造を変化させるフィルターです。例えば、膨張(拡大)や収縮(縮小)などがあります。
ここでは、平滑化フィルターの一種であるガウシアンフィルターを使ってノイズ除去を行う方法を紹介します。ガウシアンフィルターとは、正規分布(ガウス分布)に従った重み付け平均を行うフィルターです。ガウシアンフィルターは、画像の細かいノイズやテクスチャを除去しつつもエッジや輪郭を保持する効果があります。
OpenCVでガウシアンフィルターを適用するには、cv2.GaussianBlurという関数を使います。この関数は、第一引数としてNumPyの配列として表現された画像データを受け取り、第二引数としてフィルターのサイズをタプルで指定します。フィルターのサイズは、奇数である必要があります。第三引数としてフィルターの標準偏差を指定します。標準偏差が大きいほど、画像がぼやける効果が強くなります。戻り値としてフィルターが適用された画像データを返します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納されたカラー画像データにガウシアンフィルターを適用することができます。
img_blur = cv2.GaussianBlur(img, (5, 5), 0)
フィルターが適用された画像データを表示するには、先ほどと同じようにMatplotlibを使います。
plt.imshow(img_blur)
plt.show()
これで、Pythonで画像のノイズ除去ができるようになりました。
3. 画像データの特徴抽出
次に、前処理した画像データから特徴を抽出する必要があります。特徴抽出とは、画像の中に含まれるオブジェクトやパターンなどの重要な情報を数値やベクトルなどで表現することです。特徴抽出は、画像の内容を簡潔かつ効率的に表現したり、画像の分類や識別などの後続の処理に利用したりするために行われます。
特徴抽出には、以下のような方法があります。
- ヒストグラム:画像のピクセル値や色情報の分布を表すグラフです。ヒストグラムは、画像の明るさやコントラスト、色相などの全体的な特徴を表現できます。
- エッジ:画像のピクセル値が急激に変化する部分です。エッジは、画像のエッジや輪郭などの局所的な特徴を表現できます。
- 特徴点:画像の中で他と異なる部分や目立つ部分です。特徴点は、画像の角や端、テクスチャなどの細かい特徴を表現できます。
- 特徴記述子:特徴点周辺のピクセル値や方向などを数値やベクトルで表現したものです。特徴記述子は、特徴点の位置や形状、向きなどの詳細な特徴を表現できます。
ここでは、OpenCVを使ってヒストグラムとエッジを抽出する方法を紹介します。
ヒストグラム
ヒストグラムを抽出するには、cv2.calcHistという関数を使います。この関数は、第一引数としてNumPyの配列として表現されたカラーまたはグレースケールの画像データを受け取り、第二引数としてチャンネル(色情報)のインデックスをリストで指定します。例えば、RGBカラー画像では0が赤色、1が緑色、2が青色に対応します。第三引数としてマスク(対象領域)を指定します。マスクは、画像の中でヒストグラムを計算したい部分を白色、それ以外を黒色にした画像データです。マスクを指定しない場合は、Noneを指定します。第四引数としてビン(区間)の数をリストで指定します。ビンとは、ヒストグラムの横軸におけるピクセル値の範囲です。例えば、0から255までのピクセル値を256個のビンに分ける場合は、[256]と指定します。第五引数としてレンジ(範囲)をリストで指定します。レンジとは、ヒストグラムの横軸におけるピクセル値の最小値と最大値です。例えば、0から255までのピクセル値を対象とする場合は、[0, 256]と指定します。戻り値としてヒストグラムのデータを返します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納されたRGBカラー画像データから赤色のヒストグラムを計算することができます。
hist_red = cv2.calcHist([img], [0], None, [256], [0, 256])
ヒストグラムのデータを表示するには、Matplotlibを使います。plt.plotという関数を使って、ヒストグラムのデータを折れ線グラフとして描画します。引数としてヒストグラムのデータを受け取ります。また、colorというパラメータで線の色を指定します。例えば、以下のように記述すると、赤色のヒストグラムを赤色の線で表示することができます。
plt.plot(hist_red, color="red")
plt.show()
これで、Pythonで画像のヒストグラムを抽出する方法がわかりました。
エッジ
エッジを抽出するには、先ほど紹介したエッジ検出フィルターを使います。ここでは、キャニーフィルターを使ってエッジを抽出する方法を紹介します。キャニーフィルターとは、画像のピクセル値の勾配や方向などを計算し、エッジらしい部分だけを白色にし、それ以外を黒色にするフィルターです。
OpenCVでキャニーフィルターを適用するには、cv2.Cannyという関数を使います。この関数は、第一引数としてNumPyの配列として表現されたカラーまたはグレースケールの画像データを受け取ります。第二引数として最小閾値、第三引数として最大閾値を指定します。閾値とは、エッジかどうか判断するための基準値です。最小閾値より小さい勾配はエッジではないと判断し、最大閾値より大きい勾配はエッジであると判断します。最小閾値と最大閾値の間の勾配は、周囲にエッジがあればエッジであると判断し、なければエッジではないと判断します。戻り値としてエッジが抽出された画像データを返します。例えば、以下のように記述すると、先ほど読み込んだimgという変数に格納されたカラー画像データにキャニーフィルターを適用することができます。
img_edge = cv2.Canny(img, 100, 200)
エッジが抽出された画像データを表示するには、先ほどと同じようにMatplotlibを使います。ただし、グレースケールの画像の場合は、plt.imshowの引数にcmap=”gray”というパラメータを指定して、グレースケールのカラーマップを選択します。
plt.imshow(img_edge, cmap="gray")
plt.show()
これで、Pythonで画像のエッジを抽出する方法がわかりました。
4. 画像データの分類または識別
最後に、特徴抽出した画像データを分類または識別する必要があります。分類とは、画像データをあらかじめ定められたカテゴリーに分けることです。例えば、画像データが犬か猫かを判別することが分類です。識別とは、画像データが特定の個体や物体に対応するかどうかを判別することです。例えば、画像データがある人物の顔かどうかを判別することが識別です。
分類や識別を行うには、機械学習や深層学習などの人工知能の技術を使います。機械学習や深層学習とは、大量のデータからパターンや法則を学習し、未知のデータに対して予測や判断を行う技術です。機械学習や深層学習では、以下のような手順で分類や識別を行います。
- 学習用の画像データと正解ラベル(カテゴリー名や個体名など)を用意する
- 学習用の画像データから特徴抽出を行い、特徴ベクトル(特徴を数値化したもの)を作成する
- 特徴ベクトルと正解ラベルを使って、分類や識別のためのモデル(数理的な関数やアルゴリズム)を学習させる
- 学習したモデルに対して、未知の画像データから特徴抽出した特徴ベクトルを入力し、分類や識別の結果(予測ラベル)を出力させる
ここでは、Pythonで分類や識別を行うために必要なライブラリやツールを紹介します。
scikit-learn
scikit-learnとは、Pythonで機械学習を行うためのライブラリです。scikit-learnは、分類や回帰などの様々な機械学習のタスクやアルゴリズムを提供しています。scikit-learnは、NumPyやSciPyなどの科学計算用のライブラリに依存しています。
scikit-learnをインストールするには、以下のコマンドを実行します。
pip install scikit-learn
scikit-learnをインポートするには、以下のように記述します。
import sklearn
scikit-learnを使って分類や識別を行うには、以下のような手順で行います。
- データの準備:学習用とテスト用に分ける
- モデルの選択:分類や識別に適したアルゴリズムを選ぶ
- モデルの学習:学習用の特徴ベクトルと正解ラベルを使ってモデルを学習させる
- モデルの評価:テスト用の特徴ベクトルと正解ラベルを使ってモデルの精度を評価する
- モデルの予測:未知の特徴ベクトルを使ってモデルの予測ラベルを出力させる
ここでは、scikit-learnで分類や識別を行うために必要なコードの一部を紹介します。
データの準備
scikit-learnでは、sklearn.model_selection.train_test_splitという関数を使って、データを学習用とテスト用に分けることができます。この関数は、第一引数として特徴ベクトルの配列、第二引数として正解ラベルの配列を受け取ります。第三引数としてテスト用のデータの割合を指定します。例えば、0.2と指定すると、全体の20%がテスト用になります。戻り値として、学習用とテスト用に分けられた特徴ベクトルと正解ラベルの配列を返します。例えば、以下のように記述すると、Xという変数に格納された特徴ベクトルとyという変数に格納された正解ラベルを学習用とテスト用に分けることができます。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
モデルの選択
scikit-learnでは、sklearn以下のサブモジュールに分類や識別に適した様々なアルゴリズムが用意されています。例えば、以下のようなものがあります。
- sklearn.linear_model:線形回帰やロジスティック回帰などの線形モデルです。
- sklearn.tree:決定木やランダムフォレストなどの木構造モデルです。
- sklearn.svm:サポートベクターマシンなどのマージン最大化モデルです。
- sklearn.neighbors:k近傍法などの近傍法モデルです。
- sklearn.naive_bayes:ナイーブベイズなどの確率的モデルです。
- sklearn.neural_network:多層パーセプトロンなどのニューラルネットワークモデルです。
ここでは、サポートベクターマシン(SVM)というアルゴリズムを使って分類や識別を行う方法を紹介します。SVMとは、特徴空間上でマージン(境界から最も近い点までの距離)が最大になるように境界線(超平面)を引くことで、カテゴリーごとに分離するアルゴリズムです。SVMは、線形分離可能な場合だけでなく、非線形分離可能な場合にも対応できる強力なアルゴリズムです。
scikit-learnでSVMを使うには、sklearn.svm.SVCというクラスを使います。このクラスは、引数としてSVMのパラメータを指定してインスタンス化します。例えば、以下のように記述すると、Cというパラメータを1.0に指定したSVMのモデルを作成することができます。Cとは、マージンの幅と誤分類のトレードオフを表すパラメータです。Cが大きいほど、誤分類を許さずにマージンを狭くする効果があります。
from sklearn.svm import SVC
model = SVC(C=1.0)
モデルの学習
モデルのインスタンス化ができたら、学習用の特徴ベクトルと正解ラベルを使ってモデルを学習させます。モデルの学習は、fitというメソッドを使って行います。このメソッドは、第一引数として学習用の特徴ベクトルの配列、第二引数として学習用の正解ラベルの配列を受け取ります。例えば、以下のように記述すると、先ほど作成したSVMのモデルに対して、学習用の特徴ベクトルと正解ラベルを使って学習させることができます。
model.fit(X_train,y_train)
モデルの評価
モデルの学習ができたら、テスト用の特徴ベクトルと正解ラベルを使ってモデルの精度を評価します。モデルの精度は、scoreというメソッドを使って計算できます。このメソッドは、第一引数としてテスト用の特徴ベクトルの配列、第二引数としてテスト用の正解ラベルの配列を受け取ります。戻り値として精度(正解率)を返します。例えば、以下のように記述すると、先ほど学習させたSVMのモデルに対して、テスト用の特徴ベクトルと正解ラベルを使って精度を計算することができます。
accuracy = model.score(X_test, y_test)
モデルの予測
最後に、未知の特徴ベクトルを使ってモデルの予測ラベルを出力させます。予測ラベルは、predictというメソッドを使って出力できます。このメソッドは、引数として未知の特徴ベクトルの配列を受け取ります。戻り値として予測ラベルの配列を返します。例えば、以下のように記述すると、先ほど学習させたSVMのモデルに対して、未知の特徴ベクトルX_newを使って予測ラベルy_predを出力させることができます。
y_pred = model.predict(X_new)
これで、Pythonで画像データの分類や識別ができるようになりました。
まとめ
以上で、Pythonで画像認識をする方法について、初心者向けにわかりやすく解説してきました。この記事では、以下の4つの手順を踏みました。
- 画像データの入力:OpenCVを使って画像データを読み込み、表示しました。
- 画像データの前処理:OpenCVを使って画像データのサイズ変更、色空間の変換、ノイズ除去などを行いました。
- 画像データの特徴抽出:OpenCVを使って画像データからヒストグラムやエッジなどの特徴を抽出しました。
- 画像データの分類または識別:scikit-learnを使って機械学習や深層学習の技術を使って画像データを分類や識別しました。
これらの手順をマスターすれば、Pythonで画像認識をする基礎が身につくと思います。もちろん、これだけでは十分ではありません。画像認識は、様々な応用や発展がある分野です。例えば、顔認識や物体検出などの高度なタスクや、TensorFlowやPyTorchなどのフレームワークを使った深層学習の実装などがあります。これらについては、別の記事で詳しく紹介していきたいと思います。
コメント