コンテンツへスキップ

Raspberry PiにLet's EncryptのSSL証明書

現時点ですと、EncryptのSSLを発行する際に、通常の方法ですとポート80を証明書を発行したい(SSL証明書を受け取りたい)サーバーで開放する必要がありました。
よって、Raspberry Piでは、自己証明書SSLを利用しておりました。Raspberry Piの自己証明書SSL
ポート80を利用しているSynologyは、Synologyの機能を用いて、Let's Encryptの証明書を導入しております。Synology無料SSL証明書導入(Let’s Encrypt)

最近の便利さには、日々関心しておりますが、今回の驚きも大きかったです。
Apacheの設定まで確認し、必要な証明書を確認し、各種設定含め自動実行出来ます。

cerbotおよびpython-cerbot-apacheの導入

@raspberrypi:~ $ sudo apt-get install certbot
@raspberrypi:~ $ sudo apt-get install python-certbot-apache

python-cerbot-apacheをインストール祭に、次のパケケージもインストールされます。python3-augeas python3-certbot-apache

cerbot --apacheを実行し、SSL証明書発行およびapacheのSSL設定

cerbot --apacheを実行し、SSL証明書を設定したいドメインを選択し、SSL証明書の発行およびApacheのSSL関係設定を実施します。
実際には、対象ドメインの選択のみで、全て自動で設定されます。

@raspberrypi:~ $ sudo certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.domain1.com
2: aaa.domain2.com
3: www.domain2.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2,3
Obtaining a new certificate
Deploying Certificate to VirtualHost /etc/apache2/sites-enabled/aaa.domain2-ssl.conf
Created an SSL vhost at /etc/apache2/sites-available/domain2-le-ssl.conf
Deploying Certificate to VirtualHost /etc/apache2/sites-available/domain2-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/domain2-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting vhost in /etc/apache2/sites-enabled/aaa.domain2.conf to ssl vhost in /etc/apache2/sites-enabled/aaa.domain2-ssl.conf
Redirecting vhost in /etc/apache2/sites-enabled/domain2.conf to ssl vhost in /etc/apache2/sites-available/domain2-le-ssl.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://aaa.domain2.com and
https://www.domain2.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=aaa.domain2.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.domain2.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/aaa.domain2.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/aaa.domain2.com/privkey.pem
Your cert will expire on 2019-12-03. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

cerbot renewで証明書更新をテスト

証明書の有効期限が1ヶ月未満になると、証明書の再取得が行われます。
コマンド実行をテストし、次のステップで、cronの定期実行ジョブとして、コマンドラインを登録します。

@raspberrypi:/var/www/vhosts/aaa.domain2.com $ sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/domain2.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/aaa.domain2.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following certs are not due for renewal yet:
/etc/letsencrypt/live/domain2.com/fullchain.pem expires on 2019-12-03 (skipped)
/etc/letsencrypt/live/aaa.domain2.com/fullchain.pem expires on 2019-12-03 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

cronの定期実行ジョブ登録

以下の例では、毎週日曜日の深夜1時にcertbot renewが実行されるように登録しています。

0 1 * * 7 certbot renew

 

 

Apache2系のインストール

絶対難しくなった。と思うのは私だけ?
設定ファイルを分割しすぎ、直感的に分からない。
Virtual Hostに、CGIモジュール導入で苦労したので、記事にしておきます。

Apache2をRaspberry Piへインストール

Apache「apache2」、SQLサーバー「 mariadb-server」、PHPのSQLモジュール「 php-mysql」をインストールします。
MySQLサーバー「mysql-server」をインストールしようとしましたが、「パッケージ 'mysql-server' にはインストール候補がありません」と表示されました。

MariaDB は MySQL の派生のようで、今後のスタンダードになっていくオープンソースのデータベースのようです。

@raspberrypi:~ $ sudo apt-get update
@raspberrypi:~ $ sudo apt-get upgrade
@raspberrypi:~ $ sudo apt-get install apache2

@raspberrypi:~ $ sudo apt-get install mysql-server
mariadb-server-10.0E: パッケージ 'mysql-server' にはインストール候補がありません

@raspberrypi:~ $ sudo apt-get install mariadb-server

@raspberrypi:~ $ sudo apt-get install php-mysql

Apache2の設定ファイル

設定ファイル編集方法

# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf

conf-(available|enabled)、mods-(available|enabled)、sites-(available|enabled)、というディレクトリがあります。
confには設定ファイル、modsは拡張機能、sitesにはサイトの設定があります。
それぞれ「available」「enabled」の2つのフォルダが存在します。
設定ファイルを作成する際は、「available」フォルダに設定ファイルを作成し、次のコマンドで、設定ファイルを有効化、無効化します。

  • 有効化コマンド
    • a2enconf 設定ファイル有効化
    • a2enmod 拡張機能有効化
    • a2ensite サイト有効化
  • 無効化コマンド
    • a2disconf 設定ファイル無効化
    • a2dismod 拡張機能無効化
    • a2dissite サイト無効化

有効化、無効化のコマンドにより、「available」フォルダ内の設定ファイルのリンクが、「enabled」フォルダ内に作成・削除されます。

設定ファイル変更後は、apacheサービスの設定再読み込みや再起動が必要です。

設定ファイル編集

拡張機能をする際は、有効化されているモジュールを調べます。

# apache2ctl -M

「cgi_module」は、デフォルトでは有効になっていないので、以下のコマンドでCGIが利用出来るように変更します。

# a2enmod cgi
# apache2ctl -M|grep cgi
cgid_module (shared)

CGIを利用したいフォルダに「 +ExecCGI」を追記し、CGIが動作するように設定します。以下は、トップフォルダでCGIを利用出来るようにした際の例です。

<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews +ExecCGI
AllowOverride None
Order allow,deny
allow from all
</Directory>

サービス操作

参考にApache2のサービス操作のコマンドを載せておきます。

Usage: apache2 {start|stop|graceful-stop|restart|reload|force-reload}
@raspberrypi:~ $ sudo service apache2 reload
@raspberrypi:~ $ sudo service apache2 restart

参考にさせて頂いたサイト

LinuxからValue-domainのDDNS(Dynamic DNS)更新

関連記事:SynologyでValueDomain向けのDDNS設定方法

SynologyでのDDNS更新も良い機能だなと思いましたが、今回はオーソドックスにLinuxホストからValue DomainのDDNS更新方法です。
Raspberry Piで設定を実施しました。
VALUE-DOMAIN(バリュードメイン)

VALUE-DOMAINのIP更新方法

VALUE-DOMAINで本設定を行う際は、VALUE-DOMAINのポータルサイトよりIP更新時に用いるドメインのパスワードを取得する必要があります。
参考URL:https://www.value-domain.com/ddns.php?action=howto

ツールなどからのアクセス先(HTTP GET/POSTリクエスト)

https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=ドメイン名&p=パスワード&h=ホスト名&i=IPアドレス

パラメータ説明
d更新するドメインを指定します。
例:value-domain.com
p更新するドメインのパスワードを指定します。
例: 1234
h更新するドメインのホスト名を指定します。DNSレコード編集画面のホスト名と全く同じ仕様です。
例: *(全ホスト)、www、指定なしはホスト名なし
i更新するドメインのIPアドレスを指定します。指定しない場合は、自動的に接続者のIPアドレスが設定されます。
aaaaレコードが存在し、IPアドレスがIPv6フォーマットの場合、aaaaレコードのホストがアップデートされます。

Raspberry PiからVALUE-DomainのIPアドレス変更

DDNS更新のスクリプトファイル準備

設定ファイルを作成します。ドメイン名と取得したパスワードを記載します。

# Place this file on /etc/update_ddns.conf
# SECURITY: run `chmod 600 /etc/update_ddns.conf'
# to make it unreadable by non-root users.
DOMAIN=***.***
PASSWORD=**************
HOST=*

IPアドレスを更新するスクリプトです。
IPアドレス変更時に、VALUE-DOMAINにIP変更を通知します。

#!/bin/bash

CONFIG_FILE='/etc/update_ddns.conf'
IP_CACHE_FILE='/tmp/update_ddns_ip'
DDNS_CACHE_FILE='/tmp/update_ddns_result'

# sources DOMAIN= , PASSWORD= and HOST=
source $CONFIG_FILE

old_ip=`[ -e $IP_CACHE_FILE ] && cat $IP_CACHE_FILE || echo ''`
new_ip=`wget --quiet -O - 'https://dyn.value-domain.com/cgi-bin/dyn.fcg?ip'`
if [ "$old_ip" = "$new_ip" ]; then
    echo "NO CHANGE ($new_ip)"
    logger -t UPDATE_DDNS "INFO: NO CHANGE ($new_ip)"
    exit 0
fi

url="https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=$DOMAIN&p=$PASSWORD&h=$HOST&i="
result=0
wget --quiet -O - "$url" 2>/dev/null | tee $DDNS_CACHE_FILE | grep 'status=0' >/dev/null && result=1

if (( !$result )); then
    echo `date` 'FAILED'
    logger -t UPDATE_DDNS "ERROR: FAILED result:" `cat $DDNS_CACHE_FILE`
    exit 1
fi

echo $new_ip > $IP_CACHE_FILE

echo "UPDATED ($new_ip)"
logger -t UPDATE_DDNS "INFO: UPDATED with new IP:$new_ip"
exit 0

作成したファイルの実行権限を変更します。

$ sudo chmod 600 /etc/update_ddns.conf
$ sudo chmod 755 /etc/update_valuedomain_ddns

定期実行登録(crontab登録)

2分、7分、12分と5分毎にスクリプトを実行し、IPアドレスが変更していないか確認を行うように、crontabにスクリプトを登録します。

$ sudo crontab -e
2-57/5 * * * * /etc/update_ddns.sh



TP-LINK TL-ER6020でのNAT構成

PPoE2セッション構成とし、NAT可能なWANポートを2つへと構成変更を行いました。
今までのネットワーク構成は、以下のようにNAT可能なPPoE接続は1セッションであったので、Synology の外部サーバー公開とRaspberry Piの外部サーバ公開は、外部向け公開ポートを分けて、アクセス/処理の振り分けを行っておりました。

ダブルWAN構成(PPoEの2セッション構成)

TP-Link の TL-ER6020は複数WANポートをサポートしているので、このような構成でのNATも簡単に設定出来ます。今回利用しておりませんが、WAN1とWAN2両方で、WEBリクエストの着信を待ち、公開サーバーへフォワードすることも可能です。

以下が、ER6020のVirtual Server(NAT)設定となります。

  • Synology ポート80(http) WAN2を利用
  • Synology ポート443(https) WAN2を利用
  • Synology ポート53(DNS) WAN2を利用
  • Raspberry Pi ポート80(http) WAN1を利用
  • Raspberry Pi ポート443(https) WAN1を利用

TP-Link VPNルーター PPTP L2TPVPN TL-ER6020

Raspberry Pi 3B+ 高温対策

プログラムのコンパイルなど4コアすべてを使った高負荷処理でなくても、結構高めの動作温度が気になっておりました。80°C近くになっている時間もありました。

夏も終盤ですが、8月末にRaspberry Pi 3B+にファンを導入しました。小さな基盤なので、ファンも小さかったです。

想像以上の効果でした、導入前が日次平均60°C付近が、導入後50°C付近と10°C以上の効果がありました。

以下が、平均温度の推移です。

Raspberry Pi 3B+の温度制御

Raspberry Pi 3B+には、2段階の温度制御が実装されています。

  • temp_soft_limit
  • temp_limit

temp_soft_limit

Raspberry Pi 3B +のみに導入されています。60°C以上になると、CPUスピードコントロールが実施されます。CPUクロックスピード調整システムが作動し、温度調整が設定されます。この温度では、クロック速度は1400MHzから1200MHzに低下する。デフォルト値は60°Cとなっております。

temp_limit

/boot/config.txtにtemp_limit=75と記載します。
この場合、70°Cからスロットリングが始まり、CPUクロックが標準の1.2GHzから段階的に600MHzまで低速化、75°C以下を保てるようになります。
スロットル時の最低CPUクロックも同様にarm_freq_min=400などと、さらに低く設定できます。

設定省略時(デフォルト)は、85℃となります。80°Cからスロットルを絞り、85°Cを越えないように制御します。

Raspberry Pi 3B+にデュアルファンをインストール

Raspberry Pi 3B+ デュアルファン Raspberry Pi Cooling Dual Fanを取り付けた際の写真を載せておきます。

綺麗に梱包されておりました。ファンを設置するシールもしっかりとした商品が同梱されています。

少し見ずらいですが、赤と黒のケーブルを接続し、ファンをボードに設置します。

Raspberry Pi デュアルファン

Yolo3、Tiny-Yolo3での独自学習モデルをPythonに実装

画像検出に向けて、AlexeyAB Darknetを用いて、YOLO3、Tiny-YOLO3で作成した、独自学習モデルをPythonで実装します。

前提条件

YOLO2 Tiny-YOLO2 YOLO3 Tiny-YOLO3 をPythonで実装

学習済みモデル(weightsファイル)とコンフィグファイル(cfgファイル)

「darknet\build\darknet\x64\cfg\obj.data」ファイルのbackupに指定したフォルダに、学習モデル(weightsファイル)が出力されます。

classes = 7
train = train.txt
valid = test.txt
names = cfg/obj.names
backup = backup/

独自学習に用いたコンフィグファイルは、「darknet\build\darknet\x64\cfg\」フォルダ内で作成していると思いますので、独自学習時に用いたcfgファイルとなります。

これらのファイルを、画像検出を実施するRaspberry PiやサーバーのPythonファイルが読み込み可能な場所にコピーします。

Python3での実装

  • net = cv.dnn.readNetFromDarknet(CFG, MODEL)
    • CFG:学習モデル(weightsファイル)
    • MODEL:独自学習時に用いたcfgファイル
  • net.setPreferableTarget
    • net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
      Raspberry PiやWindowsなどで動作させる際のTarget指定。
      現時点では、OpenCVのYOLO向けDNNでは、GPUはサポートされておりません。
    • net.setPreferableTarget(cv.dnn.DNN_TARGET_MYRIAD)
      Intel Movidius Neural Compute Stick 2 (NCS2)を利用する際は、TargetにNCS2を指定することが出来ます。Raspberry Pi 3B +で動作確認済みとなります。

参考記事:Movidius Neural Compute Stick 2、OpenVINO™ toolkit for Raspbian* OS導入

Python3 ソースコード

サンプルスクリプトを掲載しておきます。

#!/usr/bin/env python
# coding: utf-8

target_model = "yolov3-tiny-janken_final.weights"
target_config = "yolov3-tiny-janken.cfg"

import cv2 as cv
import numpy as np

MODEL = "./janken_cfg/" + target_model
CFG = "./janken_cfg/" + target_config
SCALE = 0.00392   ##1/255
INP_SHAPE = (416, 416) #input size
MEAN = 0
RGB = True

# Load a network
net = cv.dnn.readNetFromDarknet(CFG, MODEL)
net.setPreferableBackend(cv.dnn.DNN_BACKEND_DEFAULT)
##net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
net.setPreferableTarget(cv.dnn.DNN_TARGET_MYRIAD)

confThreshold = 0.8 # Confidence threshold
nmsThreshold = 0.8  # Non-maximum supression threshold

class_names = ['active', 'goo', 'choki', 'pa', 'won', 'lose', 'draw']

def getOutputsNames(net):
    layersNames = net.getLayerNames()
    return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]

def postprocess(frame, outs):
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]

    def drawPred(classId, conf, left, top, right, bottom):
        left = int(left)
        top = int(top)
        right = int(right)
        bottom = int(bottom)
        # Draw a bounding box.
        cv.rectangle(frame, (left, top), (right, bottom), (0, 255, 0))

        label = class_names[classId] + '_%.2f' % conf

        labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1)
        top = max(top, labelSize[1])
        cv.rectangle(frame, (left, top - labelSize[1]), (left + labelSize[0], top + baseLine), (255, 255, 255), cv.FILLED)
        cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))

    layerNames = net.getLayerNames()
    lastLayerId = net.getLayerId(layerNames[-1])
    lastLayer = net.getLayer(lastLayerId)

    classIds = []
    confidences = []
    boxes = []

    if lastLayer.type == 'Region':
        classIds = []
        confidences = []
        boxes = []
        for out in outs:
            for detection in out:
                scores = detection[5:]
                classId = np.argmax(scores)
                confidence = scores[classId]
                if confidence > confThreshold:
                    center_x = int(detection[0] * frameWidth)
                    center_y = int(detection[1] * frameHeight)
                    width = int(detection[2] * frameWidth)
                    height = int(detection[3] * frameHeight)
                    left = center_x - width / 2
                    top = center_y - height / 2
                    classIds.append(classId)
                    confidences.append(float(confidence))
                    boxes.append([left, top, width, height])
    else:
        print('Unknown output layer type: ' + lastLayer.type)
        exit()

    indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
    for i in indices:
        i = i[0]
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        drawPred(classIds[i], confidences[i], left, top, left + width, top + height)

c = cv.VideoCapture(0)
c.set(cv.CAP_PROP_FRAME_WIDTH, 640) # カメラ画像の横幅を1280に設定
c.set(cv.CAP_PROP_FRAME_HEIGHT, 480) # カメラ画像の縦幅を720に設定
c.read()

r, frame = c.read()

frameHeight = frame.shape[0]
frameWidth = frame.shape[1]
# Create a 4D blob from a frame.
inpWidth = INP_SHAPE[0]
inpHeight = INP_SHAPE[1]
blob = cv.dnn.blobFromImage(frame, SCALE, (inpWidth, inpHeight), MEAN, RGB, crop=False)
   
# Run a model
net.setInput(blob)
outs = net.forward(getOutputsNames(net))
   
##print(outs)
postprocess(frame, outs)
# Put efficiency information.
t, _ = net.getPerfProfile()
label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())
cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
#対象ファイルコピー保存
target_filepath = './result.jpg'
cv.imwrite(target_filepath, frame)

昨日投稿したGit Hubからソースコードをダウンロードして、OpenCV 3.4.4を導入と類似した内容なのですが、Raspberry PiへのOpenCVにぴったりの記事を見つけたので、紹介します。また、この記事を参考に最新のOpenCV4.1.Xを導入したので、記事にしておきます。

以下の記事を参考にインストールした内容となります。

Install OpenCV 4 on Raspberry Pi

Install OpenCV 4 on Raspberry Pi

他バージョンでもこの記事の手順でインストールして、問題なくOpen CVの導入が出来ております。

現時点の最新OpenCV(4.1.1)をGitHubよりソースコードをダウンロードしインストール

事前準備

システムのディスク容量の整理を行います。

sudo apt-get -y purge wolfram-engine
sudo apt-get -y purge libreoffice*
sudo apt-get -y clean
sudo apt-get -y autoremove

インストール対象のOpen CVバージョンを変数に設定します。

cvVersion="4.1.1"

インストールに利用するフォルダを作成します。

mkdir installation
mkdir installation/OpenCV-"$cvVersion"

カレントディレクトリを変数に入れます。

cwd=$(pwd)

導入パッケージのアップデートを行います。

sudo apt -y update
sudo apt -y upgrade

swapfileサイズ変更

この手順前後で、「free -m」コマンドでスワップメモリサイズを確認してください。
以下の手順で、スワップサイズを1GBに拡張します。

sudo sed -i 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=1024/g' /etc/dphys-swapfile
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

必要パッケージのインストール

多くのパッケージを導入する必要があります。環境によっては、仮想Python環境に導入することをお勧めします。私は、Raspberry Piでは仮想環境を利用しておりません。
元の参考にしているサイトでは、一部のライブラリーを仮想環境に導入されております。

sudo apt-get -y remove x264 libx264-dev

## Install dependencies
sudo apt-get -y install build-essential checkinstall cmake pkg-config yasm
sudo apt-get -y install git gfortran
sudo apt-get -y install libjpeg8-dev libjasper-dev libpng12-dev

sudo apt-get -y install libtiff5-dev

sudo apt-get -y install libtiff-dev

sudo apt-get -y install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get -y install libxine2-dev libv4l-dev
cd /usr/include/linux
sudo ln -s -f ../libv4l1-videodev.h videodev.h
cd $cwd

sudo apt-get -y install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get -y install libgtk2.0-dev libtbb-dev qt5-default
sudo apt-get -y install libatlas-base-dev
sudo apt-get -y install libmp3lame-dev libtheora-dev
sudo apt-get -y install libvorbis-dev libxvidcore-dev libx264-dev
sudo apt-get -y install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get -y install libavresample-dev
sudo apt-get -y install x264 v4l-utils

# Optional dependencies
sudo apt-get -y install libprotobuf-dev protobuf-compiler
sudo apt-get -y install libgoogle-glog-dev libgflags-dev
sudo apt-get -y install libgphoto2-dev libeigen3-dev libhdf5-dev doxygen

# Install Python Libraries
sudo apt-get -y install python3-dev python3-pip
sudo -H pip3 install -U pip numpy
sudo apt-get -y install python3-testresources

sudo pip3 install numpy dlib

OpenCVのソースコード準備

Git HubよりOpenCVのソースコードをチェックアウト(ダウンロード)します。

git clone https://github.com/opencv/opencv.git
cd opencv
git checkout $cvVersion
cd ..

git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout $cvVersion
cd ..

OpenCVのビルドおよびコンパイル、インストール

この記事で示すコンパイルオプションは、オリジナルサイトのビルドオプションとは少し異なっております。各種ビルドオプションの説明や、失敗するビルドオプションなどは各種ブログに記載されております。個人的には、できる限りコンパイルが通りやすいビルドオプションとしております。

cd opencv
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=OFF -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules -D BUILD_EXAMPLES=ON -D ENABLE_MEON=ON ..

コンパイルです。

Raspberry Pi 3B +でコンパイル実施時は、4コアすべてを使ってコンパイルしても、6-8時間程度時間を要します。Raspberry Piの動作温度もコンパイル時間に大きく影響します。

make -j$(nproc)

コンパイルが無事に成功したら、インストールを実行してください。

make install

swqpfileサイズ変更(変更したサイズを元に戻す)

この手順前後で、「free -m」コマンドでスワップメモリサイズを確認してください。
以下の手順で、スワップサイズを拡張した1GBから100MBに戻します。

sudo sed -i 's/CONF_SWAPSIZE=1024/CONF_SWAPSIZE=100/g' /etc/dphys-swapfile
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

インストール後の確認

「python3」コマンドを実行し、「import cv2」「print(cv2.__version__)」で導入されたOpenCVのバージョンを確認します。

@raspberrypi:~ $ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.1.1

最後に

当初は、結構苦労しましたが、慣れると簡単にコンパイル、インストール出来ます。OpenCVをガリガリ利用する人は、是非、自分でソースコードより導入することをお勧めします。新バージョン新バージョンでの進化が素晴らしいライブラリです。

現時点の私のRaspberry Piに導入しているOpenCVは、「4.1.1-openvino」となります。Movidius Neural Compute Stick 2、OpenVINO™ toolkit for Raspbian* OS導入

OpenCV(3.4.4)をRaspberry PI 3 B+にインストール

OpenCVのインストール方法は、以下の3つの方法で導入できます。
特に利用した機能ができるならば、1番目の方法が手軽でお勧めです。
ただし、OpenCVを使い始めると日々進化しているOpenCVを利用したくなるので、Raspberry Piでのコンパイル方法を習得していると最新バージョンなども利用出来て便利です。現時点では、Open CVのdnnではGPUサポートが出来ていなかったりと、私自身もリリースを待っている機能が存在します。

  1. pip/pip3でインストール
  2. GitHubよりソースコードをダウンロードしインストール (この記事のメイン)
  3. コンパイル済みバイナリをダウンロードして利用 (この記事には記載しておりません)

OpenCVをpip/pip3でインストール(バージョンはPIPバージョンレポジトリに依存)

必要ライブラリのインストール

$ sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-100
$ sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
$ sudo apt-get install libatlas-base-dev
$ sudo apt-get install libjasper-dev

Open-CVインストール

$ sudo pip3 install opencv-python

「opencv-contrib-python」の方が、利用可能な機能が多いようです。
ただし、商用利用時に中が必要な、特徴検出アルゴリズムSIFTやSURFなどが含まれており、利用目的に合わせてた導入が必要です。

$ sudo pip3 install opencv-contrib-python

OpenCV(3.4.4)をGitHubよりソースコードをダウンロードしインストール

事前準備

インストール対象のOpen CVバージョンを変数に設定します。

cvVersion="3.4.4"

インストールに利用するフォルダを作成します。

mkdir installation
mkdir installation/OpenCV-"$cvVersion"

カレントディレクトリを変数に入れます。

cwd=$(pwd)

導入パッケージのアップデートを行います。
「sudo rpi-update」でRaspberry Piのファームウェアのアップデートを行います。
また、Expand Filesystemを設定していない人は、「raspi-config」よりExpand Filesystem(ファイルシステムの拡張)を利用するように設定してください。

sudo apt -y update
sudo apt -y upgrade
sudo rpi-update

swapfileサイズ変更

この手順前後で、「free -m」コマンドでスワップメモリサイズを確認してください。
以下の手順で、スワップサイズを1GBに拡張します。
viなどのエディタで、直接「/etc/dphys-swapfile」を編集しても良いです。
「CONF_SWAPSIZE=1024」を記載し、dphys-swapfileサービスを再起動すれば、スワップファイルサイズを変更できます。

sudo sed -i 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=1024/g' /etc/dphys-swapfile
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

必要パッケージのインストール

多くのパッケージを導入する必要があります。
参考とする情報ソースにより多少違いはありますが、私が導入したライブラリ群は以下となっております。

sudo apt-get -y remove x264 libx264-dev

## Install dependencies
sudo apt-get -y install build-essential checkinstall cmake pkg-config yasm
sudo apt-get -y install git gfortran
sudo apt-get -y install libjpeg8-dev libjasper-dev libpng12-dev

sudo apt-get -y install libtiff5-dev

sudo apt-get -y install libtiff-dev

sudo apt-get -y install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get -y install libxine2-dev libv4l-dev
cd /usr/include/linux
sudo ln -s -f ../libv4l1-videodev.h videodev.h
cd $cwd

sudo apt-get -y install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get -y install libgtk2.0-dev libtbb-dev qt5-default
sudo apt-get -y install libatlas-base-dev
sudo apt-get -y install libmp3lame-dev libtheora-dev
sudo apt-get -y install libvorbis-dev libxvidcore-dev libx264-dev
sudo apt-get -y install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get -y install libavresample-dev
sudo apt-get -y install x264 v4l-utils

# Optional dependencies
sudo apt-get -y install libprotobuf-dev protobuf-compiler
sudo apt-get -y install libgoogle-glog-dev libgflags-dev
sudo apt-get -y install libgphoto2-dev libeigen3-dev libhdf5-dev doxygen

# Install Python Libraries
sudo apt-get -y install python3-dev python3-pip
sudo -H pip3 install -U pip numpy
sudo apt-get -y install python3-testresources

sudo pip3 install numpy dlib

OpenCVのソースコード準備

Git HubよりOpenCVのソースコードをチェックアウト(ダウンロード)します。

git clone https://github.com/opencv/opencv.git
cd opencv
git checkout $cvVersion
cd ..

git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout $cvVersion
cd ..

OpenCVのビルドおよびコンパイル、インストール

この記事で示すコンパイルオプションは、オリジナルサイトのビルドオプションとは少し異なっております。各種ビルドオプションの説明や、失敗するビルドオプションなどは各種ブログに記載されております。個人的には、できる限りコンパイルが通りやすいビルドオプションとしております。

cd opencv
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=OFF -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules -D BUILD_EXAMPLES=ON -D ENABLE_MEON=ON ..

コンパイルです。

Raspberry Pi 3B +でコンパイル実施時は、4コアすべてを使ってコンパイルしても、6-8時間程度時間を要します。Raspberry Piの動作温度もコンパイル時間に大きく影響します。
以下のコマンドは、「make -j4」となります。

make -j$(nproc)

コンパイルが無事に成功したら、インストールを実行してください。

make install

swqpfileサイズ変更(変更したサイズを元に戻す)

この手順前後で、「free -m」コマンドでスワップメモリサイズを確認してください。
以下の手順で、スワップサイズを拡張した1GBから100MBに戻します。

sudo sed -i 's/CONF_SWAPSIZE=1024/CONF_SWAPSIZE=100/g' /etc/dphys-swapfile
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

インストール後の確認

「python3」コマンドを実行し、「import cv2」「print(cv2.__version__)」で導入されたOpenCVのバージョンを確認します。

@raspberrypi:~ $ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.1.1

最後に

当初は、結構苦労しましたが、慣れると簡単にコンパイル、インストール出来ます。OpenCVをガリガリ利用する人は、是非、自分でソースコードより導入することをお勧めします。新バージョン新バージョンでの進化が素晴らしいライブラリです。

明日の記事で、OpenCV最新バージョンの4.1.1のインストール方法を記事にします。

現時点の私のRaspberry Piに導入しているOpenCVは、「4.1.1-openvino」となります。Movidius Neural Compute Stick 2、OpenVINO™ toolkit for Raspbian* OS導入

関連記事

Movidius Neural Compute Stick 2(NCS2)ヒートシンク

予想通り、NCS2の発熱量は大きいです。特に、連続稼働させている状況では、手で触ると、長時間は触り続けられない程高温になっております。
最低限、USBの延長ケーブルで、Raspberry Piやパソコンより距離をとって、設置することは必須となります。

今回、細かなヒートシンク10個入りを購入し、写真のように片面3個、先端部に1個の計7個のヒートシンクを導入しました。
コストをかけずにすぐに導入できる熱対策なのでおすすめです。

導入後、USB接続部分より本体を触っても、触り続けられる温度へと下がっております。

USB接続外部ディスクへヒートシンク

SSD、HDDの発熱は大きいです。物理デバイスであり、高温による機器の寿命など気になります。PCや専用のNAS BOXならば熱処理も施されておりますが、Raspberry PiにSATAとUSBの変換ケースを用いて、利用する際には、この高音となるUSB接続のケースが気になります。
こちらもヒートシンクを導入し、熱対策を行います。
ヒートシンクを貼り付けたのみですが、温度変化を実感出来ます。

導入したヒートシンク(本記事で掲載している商品)

Movidius Neural Compute Stick 2向け2.5インチ外付けUSB
Intel Neural Compute Stick 2

 

 

画像検出率と処理フローで安定稼働(稼働1カ月)

2019年7月29日より稼働し、5週間。合計110回のめざましじゃんけん結果を蓄積しました。(平日25日×4回+土曜5日×2回)
最終週は、処理変更なしに、めざましテレビのめざましじゃんけん生放送中のリアルタイム画像検出を100%稼働させました。
一度しかない生放送、何気なく選んだテーマですが、ぞんぶんに楽しめる開発対象です。
機械学習部分に記事が追い付いてないのですが、現在Darknet / Tiny YOLO3を用いた画像検出を行っております。試行錯誤しておりますが、誤検出は存在してしまいます。
現在は、めざましじゃんけんの生放送に合わせた処理手順と画像検出を合わせて、画像の検出ミス時にも対応可能なシステムとしております。

画像検出と処理フロー

天気予報の晴れマークや気温の羅列、何かしらのテロップやフリップボードなど、予期せぬところで、Janken_Gooとじゃんけんでグーを出したと誤認識されることなどもあります。当初2次元であり難易度は低いと考えておりましたが、実写の報道番組という特性があり、出てくる画像パターンは多岐にわたりました。

現在のめざましじゃんけん画像検出システムは、誤検出が出たとしても、確率的に誤判定が出ないような処理フローとなっております。

Stage0:めざましじゃんけん開始前
Stage1:めざましじゃんけん開始を検出した状態(じゃんけんの手を選択する)
Stage2:出したじゃんけんの手を検出した状態(結果待ちの状態)
Stage3:めざましじゃんけん結果検出状態

めざましじゃんけん処理フロー

システムメインコンポーネント

Intel Neural Compute Stick 2