今日も微速転進

ここではないどこかへ

Android Things に入門してみる(準備編)

Android ThingsはGoogleがAndroid OSをIoT(Internet of Things)用にカスタマイズしたOS、です。

一部機能を限定し、組み込み機器向けの制御インターフェイス用のライブラリ(Things support library他)を追加したとのこと。

今のところ、Preview版という位置付け。1〜2ヶ月ぐらいで更新されている模様。


某出版社の$10セールに敗れて本を買ってしまった結果です。お察し下さい。

また未読の電子書籍が貯まっていく……。

準備

OSのイメージファイルをmicroSDに書き込んで起動するという流れはRaspbianのインストールと同じです。作業環境としてmacOSを前提にしています。

用意するもの

  • microSD カード(8GB以上)
  • ラズパイ3 一式(本体とLANケーブル、マウス、キーボード、ディスプレイ)
  • Android Studio (付属のSDKおよびadbコマンド)

microSDはSDFormatter あたりでFAT32にフォーマットしておく。

インストール時点ではキーボードとマウスはほとんど意味をなさないので不要かも。

ダウンロード

公式サイトからダウンロード。この記事を書いている時点の最新版は Android Things のPreview バージョン4.1。

developer.android.com

各ハードウェアごとにインストールイメージが異なるので注意する。ラズパイの場合は一覧表の下の方にあるandroidthings_rpi3_devpreview_4_1.zipというリンクをクリックする。

Safariでダウンロードすると勝手に展開されるので圧縮ファイルの展開については省略。

デバイス名の確認

まずはmicroSDの物理デバイス名を特定する。Windows環境の場合はRaspbianと同じ要領で。以下の手順はmacOS環境向けです。

アダプタをつけてmac本体のSDカードスロットを使用する前提。

SDFormaterでフォーマットした場合、ファイルシステムはFAT32になっているいるはず。grepで絞り込む。

$ diskutil list | grep FAT -B4

実行結果の左端の、/dev/diskXという箇所のdiskX(Xは数字)という箇所がデバイス名(BSD名ともいう)。

数字は環境依存。0とか1は内蔵フラッシュストレージなので間違えないように。

物理デバイスの番号を間違えるとデータが吹き飛ぶので慎重に。私の環境ではdisk3。


一旦、SDをアンマウント。

$ diskutil umountDisk /dev/disk3
Unmount of all volumes on disk3 was successful

別解として、「システムレポート…」(画面左上のリンゴのマーク→「このMacについて」)から表示される「システム情報」から確認することもできる。

f:id:atuyosi:20170727035122j:plain:w320

microSDへの書き込み

microSDにイメージを書き込む。いつも通りデバイス名にrをつけてrdiskとする。

$ sudo dd bs=1m if=iot_rpi3.img of=/dev/rdisk3
4352+0 records in
4352+0 records out
4563402752 bytes transferred in 361.139898 secs (12636108 bytes/sec)

そのまま待つ。5分から10数分おとなしく待つ。

完了したらmicroSDを取り外してラズパイのmicroSDスロットへ。

初期設定

microSDをセットしたら、 キーボード、マウス、LANケーブル、HDMIケーブルをつないで電源ONするだけ。主にやることはWifiの設定ぐらい。

IPアドレスさえ特定できればHDMIはなくても問題ない。

電源を入れるとAndroid Thingsロゴとバージョン番号、IPアドレスがディスプレイに表示される。

準備(macOS側)

adbコマンドを使うためにパスを通す。

Android Studioをインストールし、初期設定を完了すると、各ユーザーのホームディレクトリのLIbrary配下にAndroid SDKの関連ファイルが保存されている。このうち、Library/Android/sdk/platform-toolsにパスを通せばいい。

Bash

.profileなり.bash_profileに以下を追加する。

export PATH=$USER/Library/Android/sdk/platform-tools:$PATH

fish shell

最近、fish shellを使っていたりするので。

.config/fish/config.fishに以下を追加する。

set -x PATH $HOME/Library/Android/sdk/platform-tools $PATH

Android Things環境への接続

電源を入れると画面上にネットワークへの接続状態とIPアドレスが表示されるのでこのアドレスを指定する。

$ adb start-server

HDMIでつないだディスプレイで確認したIPアドレスを指定して接続する。

$ adb connect <ip-address>

<ip-address>は環境に応じて修正。

実行例

$ adb connect 192.168.0.5
connected to 192.168.0.5:5555

環境によっては以下のようにmDNS名を指定して接続することもできる。

$ adb connect Android.local
connected to Android.local:5555

接続状態の確認

接続状態は以下で確認できる。

$ adb devices
List of devices attached
192.168.0.5:5555    device

詳細表示(-lオプション)

$ adb devices -l
List of devices attached
192.168.0.5:5555       device product:iot_rpi3 model:iot_rpi3 device:rpi3

wifi 設定

無線LAN経由の方が便利ですねってことで。

$ adb shell am startservice -n com.google.wifisetup/.WifiSetupService -a WifiSetupService.Connect \
 -e ssid <SSID> -e passphrase <pass phrase>
Starting service: Intent { act=WifiSetupService.Connect cmp=com.google.wifisetup/.WifiSetupService (has extras) }

<SSID><pass phrase>は環境に応じて修正。別にバックスラッシュで区切らずに1行で入力してもいい。

IPアドレスが変わるとディスプレイ側の表示が変わるはず。もしくはadb shell ip aなどのコマンドでwlan0にIPがセットされているかどうか確認する。

無線LANで接続に成功したら一度切り離す。

$ adb disconnect Android.local
disconnected Android.local

LANケーブルを抜いてからadb connectコマンドで再接続。再接続の際にデバイスが見つからないかもしれないが、IPアドレスを指定すれば繋がるはず。

disconnectしてから電源を切れば次回からは自動接続される。

スクリーンショット

現状、OpenGLに対応していないらしいので、ふつうのAndroid端末のようにはいかないみたい。

ただし、動画は撮れるそうなのでそれを使う。

$ adb shell screenrecord --verbose /sdcard/screenrecord.mp4  --time-limit 1

--verboseはなくてもいい。スクリーンショットを取り出す場合は、adb pullを使う。

ファイル名および保存先のパスはscreenrecordコマンドの引数に指定したもの。

$ adb pull /sdcard/screenrecord.mp4
/sdcard/screenrecord.mp4: 1 file pulled. 0.9 MB/s (19643 bytes in 0.020s)

mp4形式の動画なので適当に変換すればいいはず。

$ ffmpeg -ss 0 -i screenrecord.mp4 -f image2 test.jpg

-fはファイルフォーマットを指定するオプション。 image2を指定した場合、出力ファイルの拡張子で自動判別される。

f:id:atuyosi:20170727171613j:plain:w320
こんな感じ。


多分続く。

参考サイト

ラズパイをプロキシサーバー(キャッシュサーバー)として使う( Raspbian & Squid )

大したネタではないですが備忘録。


複数の仮想マシンapt(あるいはyumとかHomebrewも含めて)で同じパッケージをダウンロードをするケースが結構ある。

Ubuntu 16.04の仮想マシンが複数あるとして、どっちも同じようにapt upgradeを実行すると、同じ修正パッケージを取得することになり、明らかに無駄。

ホスト側でプロキシサーバーを動かして、透過型プロキシもありかと思ったけど、ちょっと面倒だなってことでラズパイを活用してみる。

構成

仮想化ホストマシンと同じサブネット上に接続したラズパイをキャッシュサーバーとして使う。

スループットの面からすると激しくイマイチだけど、どのみち外向けの回線がWiMAX2+なので問題ない。

ラズパイのイーサネットポートは100MbpsなのでIEEE 802.11nWifiの方が速度は出るかもしれない。

要件

  • LAN内部に設置
  • ローカルホストおよび仮想マシン(ゲスト)から接続できればOK
  • ある程度大き目のファイル(100MB〜200MBぐらい)もキャッシュさせたい
  • ラズパイの microSD の空き領域の有効活用(10GBぐらいはキャッシュに使って問題ない)

インストール

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install squid
$ sudo apt install squidclient

squidclientは動作状態をチェックするためのツールです。なくても動作します。

設定

$ sudo vi /etc/squid/squid.conf

修正結果の差分は以下のとおり。

$ sudo diff -N /etc/squid/squid.conf.orig /etc/squid/squid.conf
609,611c609,611
< acl localnet src 10.0.0.0/8   # RFC1918 possible internal network
< acl localnet src 172.16.0.0/12        # RFC1918 possible internal network
< acl localnet src 192.168.0.0/16       # RFC1918 possible internal network
---
> #acl localnet src 10.0.0.0/8  # RFC1918 possible internal network
> #acl localnet src 172.16.0.0/12       # RFC1918 possible internal network
> acl localnet src 192.168.0.0/24       # RFC1918 possible internal network
676c676
< #http_access allow localnet
---
> http_access allow localnet
1738c1738
< # cache_mem 8 MB
---
>  cache_mem 16 MB
1747c1747
< # maximum_object_size_in_memory 8 KB
---
>  maximum_object_size_in_memory 16 KB
1945c1945
< # cache_dir ufs /var/spool/squid 100 16 256
---
>  cache_dir ufs /var/spool/squid 8196 16 256
1988c1988
< # maximum_object_size 20480 KB
---
>  maximum_object_size 204800 KB
3392a3393
> visible_hostname unknown
4699c4700
< # forwarded_for on
---
>  forwarded_for off

要点は、

  • ローカルネットワーク(192.168.0.0/24)からのアクセスを許可
  • キャッシュするファイルのサイズを大きく(maximum_object_size
  • 使用するディスク領域の上限を大きく(cache_dir
  • プロキシ経由であることをアクセス先に通知しない(forwarded_for

下記のコマンドで設定ファイルの書式のチェック。

$ sudo squid -k parse

エラーが出なければプロセスを起動。

$ sudo systemctl start squid

設定ファイルのリファレンス:squid : Optimising Web Delivery

有効化

問題なく動くようなら自動的にsquid起動するようにする。

$ sudo systemctl enable squid

クライアント側の設定

ブラウザからは利用するようにしてもいいが、基本的にaptgitで同じファイルをダウンロードするケースを高速化できればいいので環境変数のみセットする。

VirtualBox 上のゲスト

VirtualBoxの「環境設定」から「プロキシ」タブを選択して「手動設定」で設定する。ゲスト側は気にする必要がない。

コンソール系のツール

一度実行すればあとはコマンド履歴から再実行すればいい。ノートPCを持って外出する場合は環境変数の値を空にする。

export http_proxy=http://プロキシサーバーのIP:3128
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export rsync_proxy=$http_proxy
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"

ポート番号をデフォルトの"3128"から変更している場合はそれに合わせて修正する。

手作業で環境変数をセットするのが面倒ならArch Linuxにオンオフを切り替えるスクリプトの例が記載されているのでこれを参考にする。

プロキシ設定 - ArchWiki

sudo経由で実行するコマンドは設定しない限り環境変数は引き継がないので注意する(Arch LinuxWikiを参照。

動作状態のチェック

悲しいことにsquidclientコマンドを実行するとIPv6のポートへ接続しようとするのでエラーになる。

$ squidclient -h localhost mgr:mem
client: ERROR: Cannot connect to [::1]:3128: Connection refused

対処法としては-hIPv4のアドレスを指定する。

$ squidclient -h 127.0.0.1 mgr:mem
Sending HTTP request ... done.
HTTP/1.0 200 OK
Server: squid/2.7.STABLE9
Date: Thu, 09 Mar 2017 19:30:52 GMT
Content-Type: text/plain
Expires: Thu, 09 Mar 2017 19:30:52 GMT
X-Cache: MISS from unknown
X-Cache-Lookup: MISS from unknown:3128
Via: 1.0 unknown:3128 (squid/2.7.STABLE9)
Connection: close

Current memory usage:
Pool     Obj Size       Allocated                                        In Use         Idle                     Allocations Saved                       Hit Rate
         (bytes)        (#)      (KB)    high (KB)       high (hrs)      impact (%total)(#)      (KB)    high (KB)       portion (%alloc)       (#)      (KB)    high (KB)     (number)  (%num)  (%vol) (%num)  (number)
2K Buffer                2048    2       4       4       0.42    2       2       4      4        100     0       0       2       28      0.52    5.89    93.33   30
4K Buffer                4096    4       16      16      0.35    7       1       4      16       25      3       12      16      61      1.13    25.65   93.85   65
Store Client Buffer      4096    1       4       4       0.05    2       1       4      4        100     0       0       4       3       0.06    1.26    75.00   4
acl                        48    11      1       1       0.42    0       11      1      1        100     0       0       0       0       0.00    0.00    0.00    11
acl_ip_data                16    5       1       1       0.42    0       5       1      1        100     0       0       0       0       0.00    0.00    0.00    5
acl_list                   12    23      1       1       0.42    0       23      1      1        100     0       0       0       0       0.00    0.00    0.00    23
CacheDigest                24    1       1       1       0.42    0       1       1      1        100     0       0       0       0       0.00    0.00    0.00    1
 <skip>

他にも確認できる項目の一覧を表示する場合は、squidclient -h 127.0.0.1 mgr:を実行。

関連URL

今更な感じもしますが、ないよりマシでしょうってことで。


[2017/03/12 追記] よく考えたらgithub経由のダウンロードはHTTPS経由なんで(プロキシではキャッシュできないので)大した効果はない……。


それではまた。

openSUSE for Raspberry Pi 3 をためしてみた

いつの間にかリリースされていたようです。

openSUSEというのはドイツのLinuxディストリビューションSUSE Enterprise Linux Server のコミュニティ版です。

RedhatにおけるFedoraに近いイメージでいいのでしょうか。Fedoraよりは安定志向と思いますが。

昨年11月ごろにARM向けのリリースが告知(というか、以前にも対応していたものの、最新版は未提供だった?)が出ていたもの。

HCL:Raspberry Pi3 - openSUSE

何が嬉しいかというと、64ビットモードで動作するという点です。ラズパイ3のCPUはCortex-A53(ARMv8アーキテクチャ)で、ハードウェア的には64 bitモードをサポートしていますが 、公式のOSとしては32ビットのカーネルしか提供されていませんでした。

今回のopenSUSEは非公式のOSイメージを使うとか、もしくは自前でカーネル一式ビルドするという面倒なことをしなくても64bitモードで動くよってのが一番のポイントです。

f:id:atuyosi:20170203014729p:plain

準備

前提はRaspberry Pi 3 model B、64ビットモードで動作する方のOSイメージ、です。

OSイメージのバリエーションについて

安定版であるopenSUSE Leap 44.2と、ローリングリリスース版である openSUSE Tumbleweedの2つのバージョンがあり、さらにローリングリリスース版には無印のTumbleweed とTumbleweed (non-upstream) で合計3系統。

デスクトップ環境の違いによりトータル14パターンのディスクイメージが提供されているようです。

non-upstreamというのは意味がよくわかりません。普通、OSSでupstreamというのは特定コンポーネントのオリジナルの開発元のことを指すと思うのですが、SUSEにupstreamと言われてもさっぱりです。 CentOSでupstreamといえばRedHatRHELだったりしますが。

カーネルSUSE標準のものか、Raspberry 用のカスタム版かのことを言っているのでしょうか?

※ Leapの方のLXQt版は提供されていないようです。ダイレクトリンクは404 Not Foundになっていますし、general download directoryとやらをチェックしても存在しないようです。

FTPからダウンロードする場合はファイル名がraspberrypi3.aarch64.raw.xzのものと、efi.aarch64.raw.xzのものがあるので要注意です。

42.2 Leap、Tumbleweed、Tumbleweed (non-upstream ) のそれぞれ3系統試しましたが、私の環境ではTumbleweed (non-upstream )以外は正常に動作しませんでした。

42.2 Leap に関してはログインプロンプトが表示されるにもかかわらず自動的にGUIに切り替わるタイミングでフリーズ。一方、無印のTumbleweedは起動自体は成功しますが、GUIの起動に失敗してフリーズして使い物にならないです*1

手持ちのmicroSD 3種類で試してダメだったので、microSDとの相性ではなさそうです。HDMIモニタのせいなのか、ググっても情報がないので諦めモードです。

Tumbleweed (non-upstream )については初回起動時は途中でフリーズしますが、電源オフして再度電源を投入すると起動できました。最初はLXQt 環境で行きたかったのですが、スクリーンショットが取れなかったのでXFceに切り替え。

上記リンク先の、"Installing the 64-bit non-upstream openSUSE Tumbleweed image"という見出しの下にある"XFCE image"からダウンロード。

ファイルのチェック

Linux (Raspbian)で作業しています。macOSの場合はddコマンドのオプションに注意。余計なオプションなしでRaspbianと同様にすればいけるはずです。

まずはダウンロードしたファイルのSHAチェックサムが一致するか確認。チェックサムの記載されたファイルを入手。以下は42.2 Leap の例。

$ get http://download.opensuse.org/repositories/devel:/ARM:/Factory:/Contrib:/RaspberryPi3/images/openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz.sha256
 <skip>
$ cat openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz.sha256
 <skip>
$  sha256sum openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz
 <skip>

目視で比較はスマートではないという場合は、*.sha256ファイルとチェック対象が同一ディレクトリに存在するものとして*2下記を実行する。「完了」と表示されていれば問題なし(2行目)。警告が出ているのはチェックサムを記録しているファイルに署名がくっついているためだと思う。

$ sha256sum -c openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz.sha256
openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz: 完了
sha256sum: 警告: 書式が不適切な行が 14 行あります


なお、mac環境ではsha256sumじゃなくてshasumコマンドを使う。

$ shasum -a 256 openSUSE-Leap42.2-ARM-XFCE-raspberrypi3.aarch64-2017.01.20-Build1.1.raw.xz

*.sha256ファイルに記載のチェックサムと一致していればOK。よりスマートにやるなら-cオプションを使う。

$ shasum -a 256 -c openSUSE-Leap42.2-ARM-XFCE-raspberrypi3.aarch64-2017.01.20-Build1.1.raw.xz.sha256
openSUSE-Leap42.2-ARM-XFCE-raspberrypi3.aarch64-2017.01.20-Build1.1.raw.xz: OK
shasum: WARNING: 14 lines are improperly formatted

配布元のサイトの、対応するファイルに記載されているチェックサムと一致すればダウンロード成功。

定期的にファイルが更新されるようなのでファイル名に含まれる日付部分はダウンロードしたファイルに合わせて変更する必要あり。

microSDへのデータ書き込み

USB接続のカードリーダーをラズパイにつないで作業。microSDをセットすると勝手にマウントされるのでまずはマウント解除。

まず確実に対象デバイスをマウント解除。XXXはマウントポイント名。

$ sudo amount /media/pi/XXX


対象ファイルをddで書き込み。ラズパイ以外の環境で/dev/sdaはルートパーティションなので注意。

バイス名はdmesg | grep sdmountの出力を確認すれば特定できるはず。

$ xzcat openSUSE-Tumbleweed-ARM-XFCE-raspberrypi3.aarch64-2017.01.28-Build4.3.raw.xz | sudo dd bs=4M of=/dev/sda iflag=fullblock oflag=direct;  sync 
906+0 レコード入力
906+0 レコード出力
3800039424 バイト (3.8 GB) コピーされました、 506.372 秒、 7.5 MB/秒

macOSでは4M4mに、デバイス名にiflagoflagは外す。またデバイス名も/dev/rdiskNのようにrをつける。

私の環境では10分ぐらいでした。コーヒーでも紅茶でも飲んでのんびり待つだけ。

あとはmicroSDを取り出して、ラズパイ側に差し込んで電源ON。

f:id:atuyosi:20170203014649p:plain

インストール後の諸設定

初回起動時は普通にGUIの軌道にコケる。画面左上にアンダーバーが表示されてフリーズ。

電源をオフにして再度電源を入れるとしれっとログイン画面が表示される。

初期ユーザー名はrootでパスワードはlinuxというのがopenSUSEのデフォルトらしい。

デスクトップ環境さえ起動してしまえばあとはGUIのツールからユーザーを追加できる。

atuyosi@localhost:~> uname -a
Linux localhost.localdomain 4.4.44-8-default #1 SMP Mon Jan 30 06:03:56 UTC 2017 (345bd0b) aarch64 aarch64 aarch64 GNU/Linux

いいですね、このaarch64という文字列が見たかった。

ところでこのプロンプトは一体。

f:id:atuyosi:20170203030613p:plain

まあ別にいいけど。

初回起動時の挙動

初回起動時のみそれなりに時間がかかる。そしてフリーズする。

かなりやんちゃなことをやっている印象。三番目はかなり危険だと思うんですけど。

パーティションの拡張とかしてるせいで初回起動時にコケるのかなあと。

また、swapサイズはかなり小さかったはず。500MBぐらい。

色々

SUSEといえばGUIの管理ツールであるYast

画面左下の"openSUSE"というメニューから"Settings"をポイントして展開されるメニューから"Yast"。

f:id:atuyosi:20170203014706p:plain Yast から"Language"をクリックして"Primary Language" をJapanese にするだけ。プルダウンポックスの下のチェックボックスを有効にするとキーレイアウトも面倒を見てくれるはず。

f:id:atuyosi:20170203014626p:plain

f:id:atuyosi:20170203014809p:plain

初回は追加パッケージをインストールするようなので時間がかかる。再起動してログイン画面から言語とキーボード配列を日本語(ja_JP.UTF-8)にしてログインすればOK。

画面左下のメニューからYast を起動して、"Software Management"をクリックするとGUIでソフトウェアをインストールできる。

fcitx-mozcをインストールして一旦ログアウトしてログインし直せば、日本語も入力可能。

f:id:atuyosi:20170203020855p:plain

f:id:atuyosi:20170203021208p:plain

fcitx 自体の設定は他の環境と同じ。日本語キーボードとmozcを追加して英語キーボードを削除する。

XFce の設定

画面左下の"openSUSE"というメニューから"Settings"をポイントして"Settings Manager"。

デスクトップの外観などの細かい設定はこっちから。

そのほか

  • 画面解像度がおかしい(1824x984、変更不能?)
  • HDMIモニタのスピーカーが使えない
  • 無線LANはデバイスが見えていない?
  • 初期状態ではsshは起動していない(というか、sshのホストキーが正常に読み出せていない)
  • 初期状態では日本語入力用のソフトウェアはインストールされていない

まだベータ版なんでしょうか。そもそもユーザー数が少ないのかな。

まとめ

ベンチマークは面倒だし省略。体感速度は結局、microSDの性能次第だという印象です。

デバイスドライバ完備の Raspbian と比べると常用は厳しそう。Fedora 26に期待。


それではまた。

*1:日付が表示されるところでストップしてそこから進まない

*2:なおかつファイルのあるディレクトリに移動する

ラズパイにOpenCV 3.2 をインストールする(暫定版)

前回の記事で年内の最後の予定だったけどせっかくなので。

ほぼ作業メモみたいなものです。

環境

準備

旧バージョンのアンインストール(元からインストールされている場合のみ)

OpenCV 3.1 をビルドしたディレクトリ(私の環境では~/work/opencv-3.1.0/build*1)に移動して下記を実行。

$ sudo make uninstall

ついでにmicroSDを圧迫するのでコンパイル時の中間生成物など古いファイルは削除しておく。

作業ディレクトリの作成

適当な場所に作業ディレクトリを作成して移動。

$ mkdir work
$ cd work

依存ライブラリについては過去記事参照。

a244.hateblo.jp

ソースの入手

公式からOpenCV 本体と拡張モジュール(contrib)のソースを入手。

本体の方は"OpenCV for Linux/Mac"というリンクをクリック。拡張モジュールの方は3.2.0の"tar.gz"のリンクから。

wget でダウンロードするなら下記のようにする。

$ wget https://github.com/opencv/opencv/archive/3.2.0.zip
$ wget https://github.com/opencv/opencv_contrib/archive/3.2.0.tar.gz

展開

$ unzip opencv-3.2.0.zip
$ tar zxf opencv_contrib-3.2.0.tar.gz

本体の展開先に移動し、cmake用の出力先ディレクトリを作ってそこに移動。

$ cd opencv-3.2.0/
$ mkdir build_with_contrib
$ cd build_with_contrib

ビルド

最初から拡張モジュール(contrib)ありでビルドします。

CMake

前回と同じ要領で行くと、下記のバグ?に遭遇するのと、C++チュートリアル(Example)のビルドでこけるのでそこを踏まえてcmakeを実行。
またfreetypeというcontribのモジュールも無効化します(後述)。

github.com

TBBは並列化のためのバックエンドの一つ。つまり代替手段があるので無効化しても問題ない。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
     -D CMAKE_INSTALL_PREFIX=/usr/local \
     -D INSTALL_PYTHON_EXAMPLES=ON  \
     -D PLANTUML_JAR=/usr/share/java/plantuml.jar  \
     -D ENABLE_NEON=ON \
     -D WITH_TBB=OFF -D BUILD_TBB=OFF  \
     -D WITH_QT=ON -D WITH_OPENGL=OFF \
     -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.2.0/modules \
     -D BUILD_opencv_freetype=OFF \
     -D BUILD_EXAMPLES=OFF ..

前回との変更点は以下のとおり。

  • TBBの無効化("-D WITH_TBB=OFF -D BUILD_TBB=OFF"に変更)
  • 8行目のOPENCV_EXTRA_MODULES_PATHを3.2向けに修正
  • freetypeモジュールをビルドしないように(-D BUILD_opencv_freetype=OFF)
  • サンプルをビルドしないように( -D BUILD_EXAMPLES=OFF )

cmakeの出力で、必要なモジュールが有効になっていることを確かめる。また、freetypeがDisabledのリストに存在することを確認する。

f:id:atuyosi:20161230232146p:plain

以下参考。

CMake configuration for OpenCV 3.2 (with contrib) 2016/12/30 on Raspbian jessie · GitHub

ビルド

f:id:atuyosi:20161230225017j:plain

$ make -j4

空冷ファンありなので発熱は気にせずに4並列でコンパイル

使用しているのはUSB接続の小型ファンです。電源はHDMIディスプレイのUSBハブから確保しています。

タイムリー USBファン [ 40mm角ファンモデル ]  LittleFAN40U

タイムリー USBファン [ 40mm角ファンモデル ] LittleFAN40U

輪っかにしたマスキングテープを両面テープ代わりにして固定しているだけです。小型ファンの宿命として騒音がかなり気になります。

取り付け方法によっては振動も気になりますが、発熱による警告マークは表示されません。

インストー

$ sudo make install

普通にインストールするだけ。

動作確認

C++

過去記事と同じコードをビルドして実行できたらひとまずOKとします。

#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>

int main( int argc, char** argv){

    cv::Mat img_rgb, img_gry, img_cny;

    cv::namedWindow( "Example Gray", cv::WINDOW_AUTOSIZE );
    cv::namedWindow( "Example Canny", cv::WINDOW_AUTOSIZE );

    img_rgb = cv::imread( argv[1]);

    cv::cvtColor( img_rgb, img_gry, cv::COLOR_BGR2GRAY);
    cv::imshow( "Example Gray", img_gry );

    cv::Canny( img_gry, img_cny, 10, 100, 3, true );
    cv::imshow( "Example Canny", img_cny );


    cv::waitKey(0);
    return 0;
}

過去記事と同じです。sample.cppというファイル名で保存して下記の手順でビルド。pkg-configを使うのはデフォルトでインストールされているOpenCV 2.4が間違ってリンクされるのを防ぐため。

$ g++ `pkg-config opencv --cflags --libs` sample.cpp

以下のようにグレースケール画像とエッジ抽出の結果が表示されれば問題なし。

f:id:atuyosi:20161230234328j:plain

Python 3

Pythonはモジュールのロードのみ確認。

$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.2.0'
>>>

遭遇したエラーとその対処

以下、遭遇したエラーメッセージとその対処。基本的にビルド時に無効化しただけですが。

エラーメッセージでググった時にヒットすることを期待しています。読む必要は特になし。

TBB関連

[2017/06/08 追記]

最新の開発版では修正されているようです。そのうちリリースされるであろうOpenCV 3.3 で取り込まれると思われます。

c.f. TBB: fix build on ARM by mshabunin · Pull Request #8844 · opencv/opencv · GitHub

[追記ここまで]

エラーメッセージをメモし忘れた。現象は下記と同じ。

TBB compile error 3.1-dev · Issue #7890 · opencv/opencv · GitHub

前述の通り別の選択肢があるので無効にして回避。  

-D WITH_TBB=OFF -D BUILD_TBB=OFF

バージョン3.1の時はすんなり通ったはずなんだけど。

[2017/01/23 追記]

解決先らしきものが issuesトラッカーに投稿されている。

freetype モジュール

[2017/06/08 追記]

こちらについても最新の開発版では修正されているようです。

[追記ここまで]

ビルド自体は成功するかに見えるが、Python 3でOpenCVモジュールをロードしようとすると下記のエラーに遭遇する。

>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/libopencv_.so.3.2: undefined symbol: hb_shape

必要なライブラリであるfreetype2harfbuzzはインストールされているので問題ないはずだが、実際にはエラーになっている。

関連:OpenCVのcontribにモジュールを追加してPRしてみた - Qiita

便利なモジュールが増えるのはいいことだけど、 使わない立場からすると微妙。環境依存でビルドに失敗するからといって文句言うのは筋違いなんだけど。

Githubの最新版では修正されているかも。

関連:Fix Opencv3.2 freetype module build failed in macOS10.12 #919 by Kumataro · Pull Request #926 · opencv/opencv_contrib · GitHub

macOS環境のビルドエラーの修正だけど、他のバグも一緒にクローズされてる。なのでこの問題も修正されているかもしれない。未検証。

Example ビルドエラー

これも前述のfreetype関連なのか?

[ 84%] Building CXX object samples/cpp/CMakeFiles/cpp-tutorial-pnp_registration.dir/tutorial_code/calib3d/real_time_pose_estimation/src/RobustMatcher.cpp.o
[ 84%] Linking CXX executable ../../bin/cpp-tutorial-pnp_registration
../../lib/libopencv_freetype.so.3.2.0: `hb_buffer_get_glyph_infos' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_font_destroy' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_ft_font_create' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_buffer_add_utf8' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_buffer_destroy' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_shape' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_buffer_guess_segment_properties' に対する定義されていない参照です
../../lib/libopencv_freetype.so.3.2.0: `hb_buffer_create' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
samples/cpp/CMakeFiles/cpp-tutorial-pnp_registration.dir/build.make:345: recipe for target 'bin/cpp-tutorial-pnp_registration' failed
make[2]: *** [bin/cpp-tutorial-pnp_registration] Error 1
CMakeFiles/Makefile2:21767: recipe for target 'samples/cpp/CMakeFiles/cpp-tutorial-pnp_registration.dir/all' failed
make[1]: *** [samples/cpp/CMakeFiles/cpp-tutorial-pnp_registration.dir/all] Error 2

ぶっちゃけなくてもいいので素直にOFFにする。

-D BUILD_EXAMPLES=OFF

まとめ

最低限の確認しかしていませんが、ひとまずビルド成功です。


ではまた。

*1:buildというディレクトリは自分で作成したビルド用のディレクトリで、Makefileが存在する場所

ラズパイ公式カメラモジュール その2

前回の続きです。

部品を購入したところで取り付けないと始まりません。

a244.hateblo.jp

前提条件と準備

前提条件は以下の通り。

  • Camera Module V2.1
  • Raspberry Pi 3 model B
  • Raspbian Jessie

過去記事で使っている環境にカメラが追加されただけです。

注意点など

  • Raspbian をアップデートした状態に
  • GL Driver は無効化*1しておく

以下のコマンドを実行してOSをアップデート。

$ sudo apt update
$ sudo apt upgrade

念の為、ファームウェアもアップデートしておく。

$ sudo rpi-update

正常終了したら再起動。

以下、参考。

$ uname -a
Linux raspberrypi 4.4.38-v7+ #938 SMP Thu Dec 15 15:22:21 GMT 2016 armv7l GNU/Linux

接続と設定

カメラモジュールは静電気に弱いらしいので、周囲の金属に触れるなどして静電気を逃がしてから作業する*2

  1. ラズパイの電源を切り、しばらく待っってから*3、電源ケーブルを取り外しておく
  2. カメラ接続用のコネクタ(HDMIポートの隣)の両端の黒いツメを垂直方向に引き上げる
  3. 向きに注意しつつ、コネクタにケーブルを差し込む。青い文字の印刷されている側がUSBポート側になるように
  4. しっかり押し込んだ状態で、コネクタの黒いツメを押し込んで固定する

f:id:atuyosi:20161228025305j:plain:w320
接続後の状態

f:id:atuyosi:20161228025244j:plain:w320
反対側から

通電状態で作業しても問題ないのかもしれませんが、気軽に電源の入った状態で抜き差しできるUSBが特別なのであって、本来周辺機器は電源オフで取り外すべきかと思います。

ソフトウェア側の設定

GUI環境の場合

f:id:atuyosi:20161228031709p:plain:w320

  1. 画面左上端のメインメニューから「設定」「Raspberry Piの設定」をクリックして設定画面へ
  2. 「インターフェイス」タブの「カメラ:」の有効というラジオボタンをクリック
  3. 「OK」をクリックすると再起動を促してくるので素直に再起動

f:id:atuyosi:20161228031804p:plain:w320

CLI(CUI)環境

sudo rasps-configから設定。"5. Interfacing Options"から"P1 Camera"と順に進んで行けばOK。

f:id:atuyosi:20161229000245p:plain:w320
特に説明は不要なはず

補足:エラーの例など

ケーブルがしっかり刺さっていない(もしくはRaspbian側でカメラ用のインターフェイスが有効になっていない)状態でカメラにアクセスすると下記のようなエラーが表示される。

$ raspistill  -w 1920 -h 1080 -o try.jpg
mmal: Cannot read cameara info, keeping the defaults for OV5647
mmal: mmal_vc_component_create: failed to create component 'vc.ril.camera' (1:ENOMEM)
mmal: mmal_component_create_core: could not create component 'vc.ril.camera' (1)
mmal: Failed to create camera component
mmal: main: Failed to create camera component
mmal: Camera is not detected. Please check carefully the camera module is installed correctly

ピント調整時にケーブルを引っ張ってしまったせいで遭遇しました。

なお、カメラモジュール自体が故障している場合のエラーは不明です*4

フォーカス調整

マクロよりの条件で撮影したい場合のみ。監視カメラなどの用途であれば不用意に弄らない方がベターだと思います。もちろん自己責任で。

f:id:atuyosi:20161228025114j:plain:w320
調整用の治具

付属の治具*5の裏側をよく見ると、微妙に凹みがあるのでその部分をカメラの先端部にはめ込む*6

f:id:atuyosi:20161228025136j:plain:w320

初回のみ強めに押し付けた状態で軽く時計回りにひねってやると固定用の糊が外れるのか、すんなり回転するようになります*7

初期状態では無限遠方にピントが合うように設定されているため、時計方向にはほとんど回らないはずです。

近方にピントを合わせたいときは反時計回りに、遠方にピントを合わせたいときは時計回りに。反時計回りに回しすぎると完全なピンボケ状態になる。

時計回りに締め込んで行くとほぼ出荷時の状態に戻る。

ピント調整は接続したままの状態で問題ないです。用途に応じて撮影結果を確認しながら調整(静電気対策もお忘れなく)。

例えば以下のようにコマンドにraspistill(後述)の-tオプションに"0"ミリ秒を指定するとCtrl+Cを入力するまでプレビュー画像を撮影し続けるのでかなり楽(raspvidでも可)。

$ raspistill -t 0

raspistillraspvidでプレビュー表示の見え方が微妙に違うので目的にあった方のコマンドで確認しながら調整する。

専用コマンドで撮影

公式ドキュメントによると、カメラモジュール専用のコマンドとして、raspistillraspividraspistillyuvの3つが紹介されている。

しかしながら現在のところ、raspistillyuvではなくraspiyuv'に名称が変更されていたり、raspividyuv`が追加されているので結局全部で4つとなっている。

  • raspistill : 静止画用の画像データ取得コマンド
  • raspiyuv : YUV形式でデータ画像を取得するコマンド
  • raspivid : H264形式で動画を撮影するコマンド
  • raspividyuv : YUV420形式で動画を撮影するコマンド

それぞれオプションなし、もしくは-?オプション付きで実行するとオプション一覧が表示される。なおこれらのコマンドはlibraspberrypi-binというパッケージに含まれており、基本的に最初からインストールされている。

基本的なオプションは下記のページに一通り記載されてる。

Interface(インターフェース) 2016年09月号にカメラモジュール自体と、付属コマンドの解説が載っているのでそちらも参考に。

Interface(インターフェース) 2016年09月号

静止画の撮影

静止画を撮影するには-oオプションでファイル名を指定したうえで実行する。もうひとつ重要なのは画像を回転させるための-rotオプション。

また、-hで撮影する画像の高さ、-wで撮影する画像の幅を指定する。省略した場合は最大解像度(3280x2464)。

最大解像度未満の値を指定すると、不要な部分を切り捨てるケースと指定された解像度に縮小するケースがある。結果として指定する高さと幅の比率が画角に影響する。

$ raspistill  -w 1280 -h 800 -o test.jpg

コマンドを実行するとプレビューが表示された後、画像が保存される。プレビュー画像の表示位置と解像度は-pオプションで変更可能。

デフォルトではコマンドが実行されてから5000ミリ秒(つまり5秒)ほど待機してから撮影される。これは-tオプションで変更可能。 

以下は2秒後に撮影する例:

$ raspistill -t 2000 -o image.jpg

png形式で保存する(可逆圧縮):

$ raspistill  -o image.png -e png

-eで保存する形式を指定しない限りファイル名の拡張子によらずJPEG形式で保存される((jpg, bmp, gif, png)の4種が指定できる)。

他にもカメラの設定を変更するオプションと、夜景や花火などの特定の撮影シチュエーション向けのモード指定オプション、撮影した画像にエフェクトをかけるオプション*8がある。

撮影してみた画像

そのままでは固定できないので、Amazonで購入したクリップで挟んで固定。

f:id:atuyosi:20161229013948j:plain:w320
なんとも微妙な絵面。

下記のように画像サイズを指定する。

$ raspistill  -w 1280 -h 800 -o testimage.jpg

撮影した画像は以下のとおり(フォーカス変更前)。

f:id:atuyosi:20161229013813j:plain:w320
普通にいい感じに見える。


フォーカスをいじった後の画像。

f:id:atuyosi:20161229014426j:plain:w320 ちょっとマクロよりに調整しずぎでピントが甘い。


ちょうどいい被写体がないので微妙ですが、マクロの例(だいたい8cmぐらい)。

f:id:atuyosi:20161229021437j:plain:w320
その1

f:id:atuyosi:20161229021502j:plain:w320
その2

Interfaceの記事の通り、5cmぐらいまではいけるのは確認済み。マクロよりにすると焦点の合う範囲が狭くなるのも記事の通り。

動画は面倒なので省略。

おわりに

静電気に弱いらしいのと、オートフォーカスがない点を除けば非常にいい感じだという印象です。

気が向いたらPytonのPiCameraモジュールを使うサンプルにトライするつもりです。 トランジスタ技術なりInterfaceの記事を参考に遊んでみたいとは思っています。


ひとまずこんな感じです。

その他・関連リンク

これ1冊でできる! ラズベリー・パイ 超入門 改訂第4版 Raspberry Pi 1+/2/3/Zero/Zero W対応

これ1冊でできる! ラズベリー・パイ 超入門 改訂第4版 Raspberry Pi 1+/2/3/Zero/Zero W対応

*1:初期状態では無効なので自分で有効にしていないなら何もしなくてよい

*2:気にしすぎ?

*3:少なくとも20秒、ランプが点滅しなくなるまで

*4:率直に申し上げてそのような状況には陥りたくない

*5:購入時期によっては付属してないかもしれない。「Amazon.co.jpが販売・発送」しているものは問題なし。11月中旬にKSYに問い合わせたところ、付属しているとの回答だったのでKSYも大丈夫なはず。

*6:押し当てた状態で左右にひねるとはまり込む

*7:誤ってこれ以上回転しない方向に破損しないように意図的に緩めた状態で固定しているのだと思う

*8:あくまでもGPU側の機能

広告