【スマートものづくりエキスパート育成スクール取組】(3)カメラ画像を取得

はじめに

前回の記事【スマートものづくりエキスパート育成スクール取組】(2)撮影環境の準備より、

オリジナル撮影ボックスを製作し、撮影環境の準備ができたので、

今回はカメラからの画像を取得できるようにします。

“OpenCV”と呼ばれるライブラリを使用します。


OpenCVとは

OpenCV(Open Source Computer Vision Library)は、画像や動画を処理できるオープンソースのライブラリです。

Intelが開発したライブラリで、オープンソースとして公開されているため、誰でも無料で使うことができます。

画像の表示、写真や動画の保存、画像処理などを行うことができます。


事前準備

今回はラズベリーパイとPythonを使用します。

OpenCVをインストールしておきます。


(1)カメラ画像を取得

まずは、カメラ画像を取得して表示してみたいと思います。


次のようにソースを書きました。

import cv2

# カメラ画像取得(カメラ番号に注意)
cap = cv2.VideoCapture(0)       # カメラの接続は1台なので0番

while(True):
    # 取得
    ret, img = cap.read()
    
    # キャプチャー取得できた場合
    if ret == True:
        # カメラ画像を表示
        cv2.imshow('Image', img)        # 「Image」というウインドウ名で表示
        
    # キャプチャーエラーの場合
    else:
        print("error")      # コンソールに「error」表示
        
    # wait
    k = cv2.waitKey(30) & 0xFF      # 30msサイクル
    
    # Escキーで終了
    if k == 27:
        break
        
# 解放    
cap.release()
cv2.destroyAllWindows()


カメラからの映像が表示されました。


(2)解像度を変えてみる

解像度によっても文字認識に影響するかもしれません。

画面に表示されている解像度は640×480だったので、確認のために800×600に変えてみます。


先ほどのソースに、解像度の設定を追加しました。

import cv2
import os

# カメラ画像取得(カメラ番号に注意)
cap = cv2.VideoCapture(0)       # カメラの接続は1台なので0番

# ★解像度
cap.set(cv2.CAP_PROP_FRAME_WIDTH,800)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,600)

while(True):
    # 取得
    ret, img = cap.read()
    
    # キャプチャー取得できた場合
    if ret == True:
        # カメラ画像を表示
        cv2.imshow('Image', img)        # 「Image」というウインドウ名で表示
        
    # キャプチャーエラーの場合
    else:
        print("error")      # コンソールに「error」表示
        
    # wait
    k = cv2.waitKey(30) & 0xFF      # 30msサイクル
    
    
    # Escキーで終了
    if k == 27:
        break
        
# 解放    
cap.release()
cv2.destroyAllWindows()


解像度が変わり、先ほどより大きく表示されました。


(3)保存する

カメラ画像を保存します。

保存先のフォルダを指定し、画像ファイル名はユニークにするために現在の日付と時間にします。

画像フォーマットは、「jpg」「png」「bmp」の3種類を保存します。


キーボードの”S”キーを押すと、指定したフォルダに保存するようにします。

import cv2
import os
import datetime

# ★保存先ディレクトリパス
root = "/home/pi/opencv/picture/"

# カメラ画像取得(カメラ番号に注意)
cap = cv2.VideoCapture(0)       # カメラの接続は1台なので0番

while(True):
    # 取得
    ret, img = cap.read()
    
    # キャプチャー取得できた場合
    if ret == True:
        # カメラ画像を表示
        cv2.imshow('Image', img)        # 「Image」というウインドウ名で表示
        
    # キャプチャーエラーの場合
    else:
        print("error")      # コンソールに「error」表示
        
    # wait
    k = cv2.waitKey(30) & 0xFF      # 30msサイクル
    
    
    # Escキーで終了
    if k == 27:
        break
        
    # ★Sキーで保存
    if k == ord('s'):
        # 現在時刻
        now = datetime.datetime.now()
        
        # jpgフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".jpg"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # pngフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".png"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # bmpフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".bmp"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # 確認のためコンソールに出力
        print("save")       # コンソールに「save」表示
        
# 解放    
cap.release()
cv2.destroyAllWindows()


それぞれの画像フォーマットで保存されました。


(4)まとめて保存する

先ほど3つの画像ファイルを保存できるようになりましたが、

画像フォーマットは異なっても画像は同じなので、同じフォルダにまとめて保存したいと思います。


そこで、保存する時にフォルダ名をコマンド引数から設定し、

その設定したフォルダに保存するようにします。

import cv2
import os
import datetime
import sys

# 保存先ディレクトリパス
root = "/home/pi/opencv/picture/"

# ★コマンドライン引数
args = sys.argv

# ★コマンドの引数から取得
folderName = str(args[1])        # 保存先フォルダ名

# カメラ画像取得(カメラ番号に注意)
cap = cv2.VideoCapture(0)       # カメラの接続は1台なので0番

while(True):
    # 取得
    ret, img = cap.read()
    
    # キャプチャー取得できた場合
    if ret == True:
        # カメラ画像を表示
        cv2.imshow('Image', img)        # 「Image」というウインドウ名で表示
        
    # キャプチャーエラーの場合
    else:
        print("error")      # コンソールに「error」表示
        
    # wait
    k = cv2.waitKey(30) & 0xFF      # 30msサイクル
    

    # Escキーで終了
    if k == 27:
        break
        
    # Sキーで保存
    if k == ord('s'):
        # ★パス
        root = root + folderName + "/"
        
        # ★フォルダが存在していなければフォルダを作成
        if os.path.exists(root) == False:       # フォルダが存在していなければ
            os.mkdir(root)                      # フォルダを作成
            
        # 現在時刻
        now = datetime.datetime.now()
        
        # jpgフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".jpg"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # pngフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".png"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # bmpフォーマット
        path = root + now.strftime('%Y%m%d_%H%M%S') + ".bmp"    # ファイルパス指定
        cv2.imwrite(path, img)      # 指定したファイルパスに保存
        
        # 確認のためコンソールに出力
        print("save")       # コンソールに「save」表示
        
# 解放    
cap.release()
cv2.destroyAllWindows()


「test」という名前のフォルダに保存するようにします。

コマンドより、引数に「test」と入れて実行します。

python3 opencv_test.py test


「test」というフォルダが作成されています。


「test」フォルダの中を開けると、画像が保存されています。


同じフォルダ名を指定しても、ファイル名がユニークになっているので

再度画像を保存しても上書きされず、問題ありません。


まとめ

今回はOpenCVを使ってカメラ画像を取得してみました。

解像度の設定が変更できるので、解像度の違いによる文字認識の影響も実験できそうです。

画像フォーマットによって文字認識した時に違いがあるのか?

という素朴な疑問から、jpg、png、bmpの3種類の画像フォーマットを保存しました。

また、フォルダをわけて名前も設定できることで、

今後データを取得した時に使いやすいようにしました。


OpenCVでは画像処理を行うことができるので、次回は画像処理をやってみたいと思います。