なんでも作っちゃう、かも。

Arduino/Make/フィジカルコンピューティング/電子工作あたりで活動しています。スタバの空きカップを使ったスタバカップアンプなど製作。最近はもっぱらArduinoと3Dプリンタの自作に興味があります。

Raspberry PiでPython(とOpenCV)はじめました。

Posted by arms22 on 2016年01月26日 2  0



仕事ではC/C++を使ったプログラムを書くことが多いのですが、動的型付け言語、所謂スクリプト言語を1つマスターしたいと思いPythonを勉強することにしました。

Pythonを選んだ理由は、

  • プログラム言語別年収ランキングで一位
     国外の話で国内だとあんまり変わらないみたい。orz
  • Rubyより速そう
     バイナリパーサーを書いてみたんだけどあまりにも遅いのでPythonならどうだろう?という期待を込めて。
  • Raspberry Piにはじめから入っている
     環境構築の手間がはぶけて電子工作しつつPythonの勉強ができて一石二鳥。
  • OpenCVも使ってみたい
     OpenCVは画像処理・画像解析・機械学習用のライブラリ。データサイエンスの分野でPython+OpenCVが流行っているみたいなのでついでに。

これからPythonをはじめようと思っている方は下記チュートリアルから始めると良いと思います。実際にPythonインタプリタを動かしながら読むとすぐにコードを書けるようになります。

Python チュートリアル - Python 2.7.x ドキュメント
http://docs.python.jp/2/tutorial/

今回は前回紹介した2次元温度センサー「Grid-EYE」を使ったサーモグラフィーをRaspberry PiとPythonを使って作り直しました(上動画)。画面への表示処理にはOpenCVを使っています。

本記事では、
  • Raspberry PiからI2Cデバイスにアクセスする方法
  • Raspberry PiからOpenCVを利用する方法
を解説します。


回路


IMGP1086
Grid-EYEのピン配置・周辺回路についてはこちらの記事を参照してください。

GPIO_RaspberryPi_Model_A+_B+_and_B2
Raspberry Pi Model A+, B+, B2のピン配置図です。Model A, Bのピン配置はこのサイトを参照してください。

Raspberry PiとGrid-EYEの接続
2)SDA -- SDA1
3)SCL -- SCL1
4)INT -- 未接続
9)VDD -- +3V3
6)GND -- GND




I2Cドライバ・I2Cライブラリのセットアップ


まずはI2C関連のツールとPython用のI2Cライブラリをインストールします。
# sudo apt-get install i2c-tools python-smbus

次に raspi-config を使ってカーネルのI2Cドライバを有効にします。設定が終わったら一旦再起動します(ドライバを読み込む為)。
# sudo raspi-config
08 Advanced Options > A7 I2C > Yes
# sudo reboot

再起動したらI2Cドライバが正常に動作しているか確認してみましょう。次のコマンドを入力するとI2Cバスに接続されているデバイスのアドレスが表示されます。68はGrid-EYEです。
# sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

次のようなエラーが表示された場合、I2Cバスの番号を1から0に変えてコマンドを実行してください。
Error: Could not open file `/dev/i2c-1' or `/dev/i2c/1': No such file or directory

Raspberry Piのリビジョンによって利用できるI2Cバスが異なるようです。初期モデルのRaspberry PiはI2C0、A+, B+, B2ではI2C1が利用できます。
# sudo i2cdetect -y 0

Pythonからデバイスにアクセスできるか確認してみましょう。Pythonを起動して青色のコマンドを入力してください。Grid-EYEのサーミスタ温度が読み出せるはずです。
# python
>>> import smbus # I2Cライブラリをインポート
>>> i2c = smbus.SMBus(1) # I2Cバスアクセス用のインスタンス取得
>>> temp = i2c.read_word_data(0x68, 0x0E) # デバイスアドレス0x68のレジスタ0x0Eから2バイト読み出す
>>> temp * 0.0625 # 読み出した値に0.0625を掛けて温度に変換
29.1875



OpenCVライブラリのセットアップ


続いてOpenCVライブラリとPython用バインディングをインストールします。
# sudo apt-get install libopencv-dev python-opencv

PythonからOpenCVのバージョンを確認します。
# python
>>> import cv2 # opencvライブラリをインポート
>>> print cv2.__version__ # バージョン情報をプリント
‘2.4.9.1'

画像を読み込んで画面に表示します。
# wget http://www.cs.cmu.edu/~chuck/lennapg/lena_std.tif
# python
>>> import cv2
>>> img = cv2.imread('lena_std.tif') # wgetで取得した画像を読み込む
>>> cv2.imshow('lena_std', img) # 読み込んだ画像を表示するよう指示
>>> cv2.waitKey() # waitKeyを呼び出したタイミングで画像を表示

GdkGLExt-WARNING **: Window system doesn't support OpenGL.というエラーが発生した場合、次のライブラリもインストールしてください。Raspbian Jessie 8.0ではOpenGLがなぜか無効になっているようです。
# sudo apt-get install libgl1-mesa-dri

画像を表示するにはRaspberry PiをGUIモードで起動しておく必要があります。コンソールモードを使用している場合、次のようにXウィンドウシステムを起動し環境変数DISPLAYを設定してからPythonスクリプトを実行してください。
# startx&
# export DISPLAY=:0.0

sshでログインしている場合、Xオプションを指定してログインするとリモートホストに画面を転送することができます。リモートホスト側にXウィンドウシステムが必要です(OSXだとXQuartsとか)。
$ ssh pi@rpi.local -X
# echo $DISPLAY
localhost:11.0



サーモグラフィーのソースコード


GridEye.pyはGridEYEへのアクセス処理をまとめたモジュールです。thermistorTempはサーミスタ温度を浮動小数点型で返します。pixelOutはピクセル毎の温度を浮動小数点のリスト型で返します。

grid_eye_view.pyはサーモグラフィーのメインモジュールです。GridEYEからピクセル毎の温度データを読み出し、温度を0~255のグレースケール値に変換します。このデータを8x8のグレースケール画像として、カラー画像に変換(cv2.applyColorMap)し、512x256の表示用バッファに補完アルゴリズムを変えて2回拡大転送(cv2.resize)します。最後に画面に表示するよう指示(cv2.imshow)します。実際にはcv2.waitKeyを呼んだタイミングで画面に表示されます。

ソースコードはGitHubで公開しています。こちらからもダウンロードできます。

arms22/GridEye.py
https://gist.github.com/arms22/e62e682089fe428b1de8

アーカイブをダウンロードしてスクリプトファイル(grid_eye_view.py)に実行権を与えて実行してください。
# curl -L https://git.io/vzoKn > grid_eye_view.zip
# unzip -j -d grid_eye_view grid_eye_view.zip
# cd grid_eye_view/
# chmod +x grid_eye_view.py
# ./grid_eye_view.py



参考リンク


RPi Low-level peripherals - eLinux.org
http://elinux.org/RPi_Low-level_peripherals

Configuring I2C | Adafruit’s Raspberry Pi Lesson 4. GPIO Setup | Adafruit Learning System
https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c

Raspberry Pi B+にOpenCV-Python環境を構築する - Qiita
http://qiita.com/jh3rox/items/be803f9171db8fe737de

Enable OpenGL on Raspbian Jessie for OpenCV
https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=128464


初めてのPython 第3版
初めてのPython 第3版
posted with amazlet at 16.01.25
Mark Lutz
オライリージャパン
売り上げランキング: 64,168


詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識
Gary Bradski Adrian Kaehler
オライリージャパン
売り上げランキング: 50,249


Arduinoで赤外線アレイセンサ「Grid-EYE」から2次元の温度データを取得する

Posted by arms22 on 2016年01月03日 19  0

IMGP1082

Grid-EYEはPanasonicが開発した赤外線センサで8x8(64画素)の2次元の温度データを出力します(上写真、四角い窓の缶パッケージ)。視野角60度で広範囲の温度が計測できます。電子レンジやエアコン、また静止した人体の検出も可能なのでデジタルサイネージなどにも使われています。



とある伝でこのICのサンプルを頂いたのでサーモグラフィーを作ってみました。Grid-EYEで取得した2次元の温度データをProcessingを使って表示しています(詳細はサンプルコード2)。


回路


GridEyeサンプル回路
industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000CJ1.pdfより引用

Arduinoとの接続
2)SDA -- A4 または SDA
3)SCL -- A5 または SCL
4)INT -- 2番 または 3番
9)VDD -- 3.3V
6)GND -- GND

SDA/SCL/INT端子は10kΩの抵抗でプルアップします。その他のコンデンサ・抵抗は推奨回路どおり接続します。INTピンは割り込み信号を出力する端子です。設定した閾値を超えた時、または下回った時にLOWレベルを出力します。今回は使用しないので未配線でもOKです。電源はAMG883xなら3.3V、AMG885xなら5.0Vを接続します。


ライブラリ

Grid-EYEからピクセル毎の温度を読み込むためのライブラリを作りました。下記URLからzipファイルをダウンロードしてください。ライブラリをインストールするにはArduinoのメニューからスケッチ > Include Library > Add .ZIP Library...を選択し、先ほどダウンロードしたzipファイルを選びます。

arms22/GridEye
https://github.com/arms22/GridEye/archive/master.zip


サンプル1

Arduinoでピクセル温度データを読み込むサンプルです。サーミスタ温度とピクセル温度データを読み込み、シリアル通信で温度を文字列として送信します。シリアルモニタでサーミスタ温度とピクセル温度データが確認できます。サーミスタ温度を読み出す関数thermistorTemp()の戻り値はint型で1LSB=0.0625度です。ピクセル温度データを読み出す関数pixelOut()の第1引数には温度データを格納するint型配列を渡します。1LSB=0.25度です。



サンプル2

Processingを使ってサーモグラフを表示するサンプルです。Arduinoでピクセル温度データを読み込み、シリアル通信で1ピクセルを2バイトのshort型で下位バイト・上位バイトの順で送信します。温度データの送信前に2バイトのヘッダ(0x55、0xaa)をデータの区切りとして送信します。Processing側では130バイトのデータ(ヘッダ2バイト+ピクセル温度データ64*2)がバッファに溜まるのを待ちます。130バイト受信したらヘッダを受信したか確認します。ヘッダを受信したらピクセル温度データを変数に格納します。
受信したピクセル温度データはサーモグラフっぽく見せるために色と温度の対応を調整するのが結構大変でした。Processing側のコードはPythonで記述しています。



赤外線アレイセンサ Grid-EYE | 電子デバイス・産業用機器 | Panasonic
http://industrial.panasonic.com/jp/products/sensors/built-in-sensors/grid-eye


↓本格的なモノは結構高いですな。。



該当の記事は見つかりませんでした。