【ラズパイ】CV2 画像処理のための配列 (Python)

ラズパイで画像処理の配列

こんにちは.けい( @KeiMameshiba )です.

ラズベリーパイのカメラの使い方,画像処理をするための配列に格納する方法,についてまとめました.

この記事では,カメラの接続方法などは解説していないので注意してください.

環境構築

ラズベリーパイの画像処理でよく使用されるライブラリ,Opencvをインストールします.

次のコマンドをターミナル上で打ちます.

sudo apt-get update
sudo apt-get install python-opencv

2行目の命令でOpencvのインストールを行います.続行しますか?[Y/n],と聞かれた場合には「y」を入力して,Enterキーを押してください.

映像を表示する

コード

import picamera
import picamera.array
import cv2

with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as stream:
        # カメラの解像度を320x240にセット
        camera.resolution = (320, 240)
        # カメラのフレームレートを15fpsにセット
        camera.framerate = 15

        # ホワイトバランスをfluorescent(蛍光灯)モードにセット
        #camera.awb_mode = 'auto'
        #camera.awb_mode = 'sunlight'
        #camera.awb_mode = 'cloudy'
        #camera.awb_mode = 'shade'
        #camera.awb_mode = 'tungsten'
        camera.awb_mode = 'fluorescent'
        #camera.awb_mode = 'incandescent'
        #camera.awb_mode = 'flash'
        #camera.awb_mode = 'horizon'

        while True:
            # stream.arrayにBGRの順で映像データを格納
            camera.capture(stream, 'bgr', use_video_port=True)

            # stream.arrayをウインドウに表示
            cv2.imshow('frame', stream.array)

            # 'q'を入力でアプリケーション終了
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            # streamをリセット
            stream.seek(0)
            stream.truncate()

        cv2.destroyAllWindows()

コード解説

with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as stream:

この部分は,with as 構文を使っています.with クラス名 as 変数名:,とすることで,クラスのインスタンスを生成します.

camera.awb_modeは,お使いの環境で自由に設定してください.大抵は室内使用だと思いますので,fluorescent(蛍光灯)モードでオッケーです.

while True: 以降で,実際にカメラの画像を取得して,ディスプレイに表示させています.

camera.capture(stream, 'bgr', use_video_port=True)

生の画像データを24ビットBGR形式の配列(stream)に格納します.

24ビットとは,1つのピクセルにB=”青”,G=”緑”,R=”赤”がそれぞれ8ビット(0~255)を持っています.

つまり,今回は解像度が320×240なので,320×240×24=1843200ビットの情報量を1枚の画像が持っています.

さらにフレームレートが15なので, 1843200 ×15ビットを1秒間の間に更新し続けていることになります.やっぱり,画像って重いですね.

試しに,画像の配列がどうなっているのかを取得してみました.

[[[209 206 214]
  [210 207 215]
  [210 207 215]
  ...
  [226 229 233]
  [226 229 233]
  [226 229 233]]

 [[210 207 215]
  [211 208 216]
  [212 210 217]
  ...
  [227 230 234]
  [226 229 233]
  [227 230 234]]

 [[208 205 213]
  [211 208 216]
  [211 208 216]
  ...
  [229 229 234]
  [226 229 233]
  [226 229 233]]

 ...

 [[201 133 138]
  [202 134 139]
  [201 133 138]
  ...
  [ 82  90  93]
  [ 82  89  95]
  [ 83  90  96]]

 [[200 135 139]
  [199 134 138]
  [201 133 138]
  ...
  [ 83  91  95]
  [ 83  90  96]
  [ 83  90  96]]

 [[197 131 136]
  [198 132 137]
  [201 133 138]
  ...
  [ 83  91  95]
  [ 82  89  95]
  [ 81  88  94]]]
(240, 320, 3)

三次元配列になっています.縦横240*320のピクセルがあり,1つのピクセルに3つの色の濃さが格納されています.

3次元配列は下の図のようなイメージです.

cv2.imshow('frame', stream.array)

ディスプレイに取り込んだ画像を表示します.”frame”の部分は画像を表示するウィンドウの名前なので,何でもいいです.

stream.seek(0)
stream.truncate()

BGR画像を取得したstreamを初期化しています.このコードがないとエラーが起きます.

まとめ

ラズベリーパイで画像を取得するときに,そのまま画像をディスプレイに表示するのは,もっと簡単なコードで実行できます.

しかし,画像のイメージを生データの配列として受け取ることができれば,その後の画像処理につなげることができます.

では!