忘備録-備忘録

技術的な備忘録

Raspberry PiのカメラをGUIで操作する2

2020-01-20 22:02:36 | raspberry ...
Raspberry Piに取り付けたカメラをプレビューするソフトの続きです。opencvを使うと簡単に作成できるようです。

ライブラリのインストール
$ sudo apt install -y libopencv-dev python3-opencv

C言語
view.cpp
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
using namespace cv;

int main(int argc, char* argv[])
{
    Mat mat;
    VideoCapture vcap(0);

    if (!vcap.isOpened())
        return -1;

    while (1) {
        vcap >> mat;
        imshow("camera", mat);
        if (waitKeyEx(10) > 0) {
            break;
        }
    }
    return 0;
}

コンパイル&実行
$ g++ view.cpp -o view `pkg-config --cflags opencv` `pkg-config --libs opencv`
$ ./view

Python
import cv2

def camera_capture():
  cap = cv2.VideoCapture(0)

  while True:
    ret, frame = cap.read()

    cv2.imshow('camera capture', frame)

    key = cv2.waitKey(1)
    if key == 27:
      break

  cap.release()
  cv2.destroyAllWindows()

if __name__=='__main__':
  camera_capture()


参考


Raspberry PiのカメラをGUIで操作する

2020-01-20 21:12:16 | raspberry ...
Raspberry Piに取り付けたカメラをプレビューするソフトがないので、探してみたらちょうどよいのがありました。
このままではうまく動作しなかったので少し変更しました。

ルーツのインストール
$ sudo apt install -y dpkg-dev build-essential python3.7-dev libpython3.7-dev
$ sudo apt install -y freeglut3-dev libgl1-mesa-dev libglu1-mesa-dev libgstreamer-plugins-base1.0-dev libgtk-3-dev
$ sudo apt install -y libjpeg-dev libnotify-dev libpng-dev libsdl2-dev libsm-dev libtiff-dev libwebkit2gtk-4.0-dev
$ sudo apt install -y libxtst-dev libgtk2.0-dev libwebkitgtk-dev python3-scipy
$ sudo apt install -y gpac

$ pip3 install wxPython

コード
#
import os
import wx
import time
import picamera

class MyFrame(wx.Frame):

    def __init__(self):
        # common
        #(w, h) = wx.DisplaySize()
        (self.w, self.h) = (int(1280/2),int(720/2))
        font = wx.Font(18, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        wx.Frame.__init__(self, None, -1, "Camera Control", pos=(0,0), size=(self.w, self.h) )
        # window
        self.Bind( wx.EVT_ACTIVATE, self.Child_activate )
        self.Bind(wx.EVT_SIZE, self.on_resize)
        self.Bind(wx.EVT_MOVE, self.on_move)
        # btnRecord
        self.btnPhoto = wx.Button(self, -1, "Pht", pos=(0,0+30),size=(80, 80))
        self.btnPhoto.Bind(wx.EVT_BUTTON, self.OnPhotoButton)
        self.btnPhoto.SetFont(font)
        # btnRecord
        self.btnRecord = wx.Button(self, -1, "Rec", pos=(0,80+30),size=(80, 80))
        self.btnRecord.Bind(wx.EVT_BUTTON, self.OnRecordButton)
        self.btnRecord.SetFont(font)
        # btnZoom
        self.btnZoom = wx.Button(self, -1, "Zoom", pos=(0,160+30),size=(80, 80))
        self.btnZoom.Bind(wx.EVT_BUTTON, self.OnZoomButton)
        self.btnZoom.SetFont(font)
        # btnClose
        self.btnClose = wx.Button(self, -1, "Close",  pos=(0,240+30),size=(80, 80))
        self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseButton)
        self.btnClose.SetFont(font)
        # lblText
        self.lblText = wx.StaticText(self, wx.ID_ANY, 'Cam',pos=(0,0))
        self.lblText.SetFont(font)
        # Camera
        self.camera = picamera.PiCamera()
        self.camera.vflip = True
        self.camera.hflip = True
        self.camera.resolution = (1280,720)
        self.camera.start_preview(fullscreen=False,window=(85, 5, self.w - 100, self.h + 40))
        # Flg
        self.isRecord = False
        self.isZoom = False

    def OnPhotoButton(self, event):
        self.Photo()

    def OnRecordButton(self, event):
        self.isRecord = not self.isRecord
        if self.isRecord == True:
            self.btnRecord.SetLabel('Stop')
            self.Record()
        else:
            self.btnRecord.SetLabel('Record')
            self.Stop()

    def OnZoomButton(self, event):
        self.isZoom = not self.isZoom
        if self.isZoom == True:
            self.camera.zoom = (0.2, 0.2, 0.6, 0.6)
        else:
            self.camera.zoom = (0.0, 0.0, 1.0, 1.0)

    def OnCloseButton(self, event):
        if self.isRecord == True:
            self.Stop()
        self.camera.stop_preview()
        self.camera.close()
        self.Close()

    def Photo(self):
        self.lblText.SetLabel('take photo...')
        self.camera.capture('photo.jpg')
        os.system('mv photo.jpg ~/Desktop/photo.jpg')
        self.lblText.SetLabel('take photo...ok')

    def Record(self):
        self.lblText.SetLabel('recording...')
        self.camera.start_recording('movie.h264')

    def Stop(self):
        self.lblText.SetLabel('output...')
        self.camera.stop_recording()
        # print('start...')
        os.system('MP4Box -fps 30 -add movie.h264 movie.mp4')
        os.system('rm movie.h264')
        os.system('mv movie.mp4 ~/Desktop/movie.mp4')
        self.lblText.SetLabel('output...movie.mp4')
        # print('end')

    def Child_activate(self,event):
        pos = self.GetScreenPosition()
        (x,y) = pos
        size = self.GetSize()
        (w,h) = size
        
        if( event.GetActive()):
            self.camera.start_preview(fullscreen=False,window=(x+85, y+5, w - 100, h + 40))
        else:
            self.camera.stop_preview()

    def on_resize(self, event):
        pos = self.GetScreenPosition()
        (x,y) = pos
        size = self.GetSize()
        (w,h) = size
        self.camera.stop_preview()
        self.camera.start_preview(fullscreen=False,window=(x+85, y+5, w - 100, h + 40))

    def on_move(self, event):
        pos = self.GetScreenPosition()
        (x,y) = pos
        size = self.GetSize()
        (w,h) = size
        self.camera.stop_preview()
        self.camera.start_preview(fullscreen=False,window=(x+85, y+5, w - 100, h + 40))

if __name__ == '__main__':
    app = wx.App()
    myapp = MyFrame()
    myapp.Show()
    app.MainLoop()

参考

Raspberry pi python3をデフォルトに設定

2020-01-16 21:42:16 | raspberry ...
Raspberry piはpythonが2系列と3系列の2種類がインストールされておりデフォルトで2系列が動作します。これを3系列に変更します。

確認
pi@raspberrypi:~ $ sudo update-alternatives --list python
update-alternatives: エラー: python の alternatives がありません

設定
pi@raspberrypi:~ $ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python2 を使います
pi@raspberrypi:~ $ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python3 を使います

確認
pi@raspberrypi:~ $ python --version
Python 3.7.3

バージョンの変更
pi@raspberrypi:~ $ sudo update-alternatives --list python
/usr/bin/python2
/usr/bin/python3
pi@raspberrypi:~ $ sudo update-alternatives --config python
alternative python (/usr/bin/python を提供) には 2 個の選択肢があります。

選択肢パス優先度状態
------------------------------------------------------------
* 0            /usr/bin/python3   2          自動モード
   1            /usr/bin/python2   1          手動モード
   2            /usr/bin/python3   2          手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 0

pipも同じバージョンにしておかないと良くないので
$ sudo update-alternatives --list python
update-alternatives: エラー: python の alternatives がありません
$ sudo update-alternatives --list pip
update-alternatives: エラー: pip の alternatives がありません
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python2 を使います
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python3 を使います
$ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip2 1
update-alternatives: /usr/bin/pip (pip) を提供するために自動モードで /usr/bin/pip2 を使います
$ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 2
update-alternatives: /usr/bin/pip (pip) を提供するために自動モードで /usr/bin/pip3 を使います
$ sudo update-alternatives --list python
/usr/bin/python2
/usr/bin/python3
pi@raspberrypi:~ $ sudo update-alternatives --list pip
/usr/bin/pip2
/usr/bin/pip3
$ sudo update-alternatives --config python
alternative python (/usr/bin/python を提供) には 2 個の選択肢があります。

  選択肢    パス            優先度  状態
------------------------------------------------------------
* 0            /usr/bin/python3   2         自動モード
  1            /usr/bin/python2   1         手動モード
  2            /usr/bin/python3   2         手動モード

現在の選択 [*] を保持するには 、さもなければ選択肢の番号のキーを押してください:
$ sudo update-alternatives --config pip
alternative pip (/usr/bin/pip を提供) には 2 個の選択肢があります。

  選択肢    パス          優先度  状態
------------------------------------------------------------
* 0            /usr/bin/pip3    2         自動モード
  1            /usr/bin/pip2    1         手動モード
  2            /usr/bin/pip3    2         手動モード

現在の選択 [*] を保持するには 、さもなければ選択肢の番号のキーを押してください:
$

参考

TensorFlowインストール

2020-01-10 22:26:53 | raspberry ...
Raspberry piにTensorFlowをインストールしたときのメモです。

ハードウェア
Raspberry pi 4 4GB

環境確認
pi@raspberrypi:~/work $ python3 -V
Python 3.7.3
pi@raspberrypi:~/work $ pip3 -V
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

インストール
pi@raspberrypi:~/work $ sudo apt install libatlas-base-dev
pi@raspberrypi:~/work $ pip3 install tensorflow
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting tensorflow
   Downloading https://www.piwheels.org/simple/tensorflow/tensorflow-1.14.0-cp37-none-linux_armv7l.whl (79.6MB)
     55% |█████████████████▉               | 44.3MB 4.6MB/s eta 0:00:08
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
     tensorflow from https://www.piwheels.org/simple/tensorflow/tensorflow-1.14.0-cp37-none-linux_armv7l.whl#sha256=d4b1c2eda7a46e00e5091c077958c1bc116fc2be6c5ecb870a613edac2a95e74:
         Expected sha256 d4b1c2eda7a46e00e5091c077958c1bc116fc2be6c5ecb870a613edac2a95e74
              Got        23acc899ae0ac258d239c8a100c884763bbdbb613b6ddb516c2305f0a7c78924

ダウンロードエラーでインストールできなかったので、直接ダウンロードしてインストールしました。
pi@raspberrypi:~/work $ wget https://www.piwheels.org/simple/tensorflow/tensorflow-1.14.0-cp37-none-linux_armv7l.whl
pi@raspberrypi:~/work $ pip3 install tensorflow-1.14.0-cp37-none-linux_armv7l.whl


動作チェック
下記のtest.pyファイルを作成します。
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))

実行します。
pi@raspberrypi:~/work $ python3 test.py 
2020-01-10 10:15:57.796165: E tensorflow/core/platform/hadoop/hadoop_file_system.cc:132] HadoopFileSystem load error: libhdfs.so: cannot open shared object file: No such file or directory
WARNING:tensorflow:From test.py:3: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.

B’Hello, TensorFlow!’

エラーメッセージは表示されるが動作はしているようです。エラーメッセージを表示させないようにするにはhadoopをインストールする必要があるらしいことがわかりました。

画像の判定(サンプルプログラム)
classify_image.pyを
https://github.com/tensorflow/models/blob/master/tutorials/image/imagenet/classify_image.py
からダウンロードします。実行すると次のようになります。
pi@raspberrypi:~/work $ python3 classify_image.py 2> /dev/null
giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89107)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00779)
lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00296)
custard apple (score = 0.00147)
earthstar (score = 0.00117)

つぎに動物(ここでは猫)の写っている画像を用意して実行します。
pi@raspberrypi:~/work $ python3 classify_image.py --image_file neko.jpg 2> /dev/null
tabby, tabby cat (score = 0.48554)
tiger cat (score = 0.19503)
Egyptian cat (score = 0.10221)
lynx, catamount (score = 0.03373)
French bulldog (score = 0.00182)

動作しているようです。

参考