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

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


Ads by Google

2 Comments

ntaka says..."clock stretching"
私もPythonの勉強兼ねつつ、RasPi + 温度センサーで遊んでみようと考えており、大変参考になりました。
そこで質問なのですが、管理者様はI2CのClock stretchでハマッた経験などおありですか?
Webでいろいろ検索するとRasPi(のドライバ?,Chipの不具合?)では、総じてClock stretchに対応できないとの情報が散見されます。
もし、何かしらのご経験をお持ちでしたら、コメントいただけますと嬉しいです。
2016.04.08 09:53 | URL | #- [edit]
arms22 says...""
直接関係するかわかりませんがブロックリード・ライトのAPIを使うとカーネルがハングアップする現象がありました。

read_block_data
write_block_data

の変わりに

read_word_data
write_word_data

を使うことで回避しました。
2016.04.17 09:43 | URL | #j7sy4omY [edit]

Leave a reply






管理者にだけ表示を許可する

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