LoginSignup
6
7

More than 5 years have passed since last update.

python + openCV で画像処理のさわりだけやってみた

Last updated at Posted at 2019-01-12

テクスチャ画像認識やることになったので、フーリエ変換とか出来るようにopenCVを触ってみました。

試行環境

  • Windows 10 64bit
  • Python 3.6.6
  • opencv-python==4.0.0.21
  • Pillow==5.3.0
  • jupyter notebook

1. PILなのかopenCVなのか

pythonの画像処理パッケージではopenCVとPILが人気のようで「python 画像処理」あたりで検索するとこの2つについての記事がほとんどです。歴史ある画像処理のデファクトスタンダードであるopenCVと、名称通りpythonの標準的な画像パッケージであるPIL(Python Image Library)の2つのパッケージですが現在はどちらもpip installで手軽に試せちゃうみたいです。どちらが良いか分からなかったので両方ちょっと触ってみました。

openCV PIL
インストール pipだけで出来る pipだけで出来る
日本語PATH 読めない 読める
カラー画像の形式 BGR RGB
グレースケール化 できる できる
HSV化 できる できる
CIE Lab化 できる できる
フーリエ変換 numpyでやる numpyでやる

どうやらやりたい事はどちらも出来るようです。もっと高度な処理になると画像処理のデファクトスタンダードであるopenCVにしかない機能がたくさんあるようですが、今回はちょろっと変換するだけなのでPILでも大丈夫みたいですね。

ただし、openCVは日本語PATHが入ると読めなくなっちゃうし、データがRGBじゃなくBGR順で入っててややこしいのが難点です。「開きたい画像ファイル1000個が全部日本語名です」みたいな時はリネームしなくても読めるPILでやった方が楽かもですね。openCVは画像データをnumpy.arrayそのままで扱えますし、PILもnumpy.arrayに変換して戻してが出来ますから、PILで読んでopenCVに渡してというのでも良いのかもしれません。

僕は今後高度な処理をやっていく可能性があるのでopenCVの方でやっていく事にしました。

2. openCVのインストールとimport

pipでサクッとインストールできます。インストールするときと使うときで名前が違うので注意。

$ pip install opencv-python
>>> import cv2

3. 画像の読み込みと表示

cv2.imread(画像ファイルのPATH)で読めます。相対PATHでも絶対PATHでも良いようです。cv2.imread()の返り値はnp.ndarrayで返ってくるので、値を直接いじったりも簡単に出来ちゃいます。

>>> import cv2
>>>
>>> im = cv2.imread('image.png')
>>> print(im.shape, type(im))

(183, 275, 3) <class 'numpy.ndarray'>

解像度が183 x 275 pixelのRGB画像だと上記のように読み込まれます。3次元のnumpy.arrayになってるので1チャンネルだけ取り出すのも簡単です。

>>> im[:, :, 0]

array([[255, 255, 255, ..., 250, 250, 250],
       [255, 255, 255, ..., 250, 250, 250],
       [255, 255, 255, ..., 250, 250, 250],
       ...,
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)

jupyter notebookで表示する場合は、cv2.imshow()が使えないようですがmatplotlib.pyplot.imshow()で表示できます。読んできた値はBlue, Green, Redの順で格納されているんですが、matplotlib.pyplot.imshow()はRGB順でデータが来るつもりで表示しちゃうので、cv2.cvtColor()で並べ替えして表示します。pyplotのメソッドなので表示解像度を変えたり並べて表示したりも出来て便利です。

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(dpi=50)
plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
plt.show()

image.png

ちなみにcm2.cvtColor()で変換しないで表示してみると、RGBが入れ替わってるので色が変になります。

plt.imshow(im)

image.png

ゲルバナ感あります。

4. グレースケール化、HSV化、Lab化

PILだと使うメソッドがそれぞれ違ってしまうのでややこしいんですが、openCVだといずれもcv2.cvtColor()で変換できます。

グレースケール化

gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
plt.figure(dpi=50)
plt.imshow(gray, 'gray')
plt.show()

image.png

HSV化

hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
plt.figure(dpi=50)
plt.imshow(cv2.cvtColor(hsv, cv2.COLOR_BGR2RGB))
plt.show()

image.png

Lab化

Lab = cv2.cvtColor(im, cv2.COLOR_BGR2Lab)
plt.figure(dpi=50)
plt.imshow(cv2.cvtColor(Lab, cv2.COLOR_BGR2RGB))
plt.show()

image.png

5. フーリエ変換

グレースケール化してからパワースペクトル出してみます。

import numpy as np

gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
fim = np.fft.fft2(gray)
fshift = np.fft.fftshift(fim)
fMagnitudeSpectrum = 20 * np.log(np.abs(fshift))
plt.figure(dpi=50)
plt.imshow(fMagnitudeSpectrum, 'gray')
plt.show()

image.png

エンジョイ!
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7