【Python】OpenCVを使ったimageファイルの画像処理の基礎

Pythonの応用
スポンサーリンク

画像ファイルとNumPyの配列(Array)との関係を使って画像処理にpillow(PIL)を使った操作は行いました。

【Python】NumPyのarrayとimageファイルで画像処理 - pillow(PIL)
PythonのライブラリーNumPyの配列を使って画像ファイルを操作します。ここでは画像処理ライブラリのpillow(PIL)を導入し、RGBカラーモデルの表現も確認します。読み込んだ画像ファイルデータのカラーを変換する操作を行います。

Pythonのデータ分析ではNumPy、Pandas、Matplotlibなどのライブラリを使いますが、機械学習の中で画像認証と言ったものも扱われており、画像や動画の処理の扱い方を知っておきたいところです。

画像や動画の処理に特化した外部ライブラリにOpenCVというものあります。ここではPythonとOpenCVを使って基本的な画像処理を学んでいこうと思います。

スポンサーリンク

OpenCVのインストール

MacにOpenCVをインストールしましょう。ここではAnacondaの環境なので、ターミナルからcondaを使って次のコマンドでインストールします。

あるいは、Anaconda Navigatorからインストールすることもできます。

HomebrewがインストールされているMacであれば、次のコマンドでもインストールできます。

pipでもインストールできますが、これは非公式のパッケージをインストールするコマンドになります。

これはvenvなどの仮想環境にインストールして使用するのが良さそうです。

Pythonで使うときのインポートは次のコードは次のコードで行います。

ちなみに、OpenCVのドキュメントはこちらになります。

OpenCV: OpenCV modules

では、画像処理を行っていきましょう。

スポンサーリンク

Jupyter notebookで画像ファイルを開く

それではOpenCVを使って画像を読み込んでみましょう。pillow(PIL)を使った画像処理は既に行いましたが、同じ画像ファイルを利用して操作してみようと思います。

ライブラリのインポート

jupyter notebookを使って画像処理をする為に、ライブラリをインポートしましょう。

OpenCVをインポートするには、cv2と入力します。

合わせて、NumPy、Matplotlibもインポートします。

jupyter notebook上に画像を表示する為に%matplotlib inlineも記述しています。

imread()で画像を読み込む

画像を読み込むにはcv2.imread()を使います。

作業ディレクトリにimagesフォルダを作って、画像ファイルのapples.jpgを配置しています。パスを正しく指定してimread()に渡しています。

実行するとこうなります。

(縦長になってしまうので表示の途中で切っています)

画像データのそれぞれの位置のカラーデータが配列として表示されています。

plt.imshow()を使って画像を表示してみます。

読み込んだ画像データの配列のimgオブジェクトを渡しています。

なぜか青色っぽく画像が表示されてしまいました。

これはOpenCVのcv2.imread()で取得した画像のカラーデータはBGR(青、緑、赤)のデータ配列になっているのに対し、Matplotlibのplt.imshow()で呼び出す場合のカラーデータはRGB(赤、緑、青)のデータ配列として処理している為です。

これをきちんと色合いで表示するにはBGRをRGBに返還して処理する必要があります。

そのためにはcv2.cvtColor()を利用します。

cvtColor()にimgを、変換コードのcv2.COLOR_BGR2RGBを使って渡すことでBGRをRGBに返還しています。

表示するとこうなります。

通常のカラーで表示されました。

今度はグレースケールで画像を読み込んでみます。

cv2.imread()で画像を読み込む時に、第2引数にcv2.IMREAD_GRAYSCALEを渡すことでグレーで表示することができます。

BGRとRGBの違いからplt.imshow()で表示するとその影響がでるので、cmap=’gray’を指定して表示します。

このimread()の第2引数は1、0、-1の整数値でも指定できますが、次のフラグとそれぞれ対応しています。

  • cv2.IMREAD_COLOR (カラー画像として読み込見ます。画像の透明度は無視され、これはデフォルト値として設定されています。)
  • cv2.IMREAD_GRAYSCALE (グレースケール画像として読み込みます。)
  • cv2.IMREAD_UNCHANGED (アルファチャンネルも含めた画像として読み込見ます。)

画像サイズの変換 – resize()

画像のサイズを変更してみましょう。

まず、画像の形状をshape()を使って調べてみます。

1066行、1600列、つまりheihtが1066px、widthが1600px、3カラーチャンネルの画像データでになります。

指定のサイズに変換

画像のサイズを変換するにはcv2.resize()を使います。

画像ファイルデータを格納してimg_rgbオブジェクトをresize()に渡します。画像サイズをタプルで一緒に渡しています。ここではwidthが1066px、heihtが200pxです。

画像サイズが変換されているのがわかります。

指定の比率で画像サイズを変換

次は元の画像を指定の比率を指定してサイズを変えてみます。

画像の幅と高さをどちらも半分の0.5にします。resize()に元画像を渡し、基準の位置を画像の左上である(0, 0)に起き、比率を指定しています。

表示させてみます。

表示されている画像の目盛りを見ると、画像の大きさが半分になっているのがわかります。

画像の反転 – flip()

次は画像の反転をやってみましょう。

画像を反転させるにはcv2.flip()を使います。

x軸反転(上下反転)

画像を上下反転させるにはx軸で回転させたらいいですね。

x軸で回転させるには、flip()に画像を渡して、0を指定します。

y軸反転(左右反転)

今度は、上下反転させた画像を左右で反転させてみます。

左右を反転させるにはy軸で回転させます。flip()に画像を渡して、今度は1を指定します。

xy軸反転

今度は、画像を対角線を軸に反転させてみます。x軸、y軸それぞれ反転させることです。ここでは最初の画像の位置に戻ることになります。

flip()に画像を渡して、今度は-1を指定します。

画像の保存 – imwrite()

操作した画像を新たに保存してみましょう。新しく画像ファイルに書き込むことになり、imwrite()を使います。

imwrite()に保存する場所のパスとファイル名を指定し、元の画像のオブジェクトを渡します。

Trueとかえっきたら画像の保存ができています。指定のパスのディレクトリに、新しく画像ファルができているはずです。ただ、この画像はRGB型ではなくBRG型のカラーで保存されることになるので注意です。そのまま開けば青系の画像になっています。

画像を表示するサイズを調整

resize()などは画像そのものの大きさを変更してしまう訳で、それを保存した場合も画像サイズは変わってしまいます。

そこで、表示のみの大きさを変更することができると便利です。

figsizeに図の幅と高さをタプルで指定してfigure()に渡します。そこにadd_subplot()で表示する位置を指定します。(111)は1行1列の1番目という意味で、画像の左上の位置を示しています。(1,1,1)としても同じです。

画像の目盛りはそのままですが、表示が小さくなっているのがわかると思います。この表示の方法はMatplotlibの使い方を確認するといいでしょう。

スポンサーリンク

ターミナルから画像ファイルを別windowで開く

これまでjupyter notebook上に画像を表示してきました。これをnotebook上にではなく別windowで開くこともできるのですが、Macでのjupyter notebook上では動画にエラーがでることが多いようです。具体的には表示した後にカーネルが止まるといった症状です。

ですので、ここではPythonスクリプトファイルにコードを書いて、ターミナルから実行して画像を別windowで開く操作をやってみましょう。

次のコードを試しにjupyter notebookで実行すると、画像を表示した後に止まってしまいます。

imread()で画像を読み込み、imshow()でビューワーのタイトルにAPPLESと示して画像を別windowで表示します。

waitKey()でキー入力を待ち続けますが、何かキーを押すとwindowが閉じて終了します。

jupyter notebookでは止まってしまいますが、テキストエディタで記述してターミナルで実行すればキチンと動作します。

このコードを次のようにもう少し変更してみます。

先ほどのコードと違うところは、while文を使ってTrueの間に画像処理を行っているところです。ここで画像が別窓で開きます。

そしてwaitKey(1)で1ミリ秒待ち、かつEscキーを押したら終了するというif文を入れています。0xFF == 27 は64ビットのPCで[esc]キーを意味しています。[esc]キーを押せば画像表示が終了することになります。ちなみに、0xFF == ord(‘q’) とすると[q]キーを押せば終了するのでquitと意味でよく見られますね。(ASCIIコード表を参照してください)

最後のdestroyAllWindows()で全てのwindowを閉じます。

上記のPythonスクリプトをターミナルからpythonコマンドで実行すると、別窓で画像が表示されるはずです。

スポンサーリンク

最後に

画像や動画の処理に特化した外部ライブラリにOpenCVというものあります。このライブラリをPythonにインポートして画像処理を行うことができます。

通常、カラーコードはRGBで表されることが多いですが、OpenCVで画像を扱うとBGRで処理されるのでmatplotlibを使って表示をする時は注意が必要です。

jupyter notebookでは、画像表示を別windowで行うとカーネルが止まってしまうことがMacやLinuxなのでは起こることがあるので注意が必要です。その場合はPythonスクリプトのファイルとしてコードを用意し、ターミナルから実行することにしましょう。