ラズパイのSDカードの書き込みを極力少なくする方法

0

    ラズパイのSDカードの書き込みを極力少なくする方法

     

    機種:Raspberry PI 3B
    OS:Raspbian JESSIE Lite

     

    ラズパイを連続使用していると1ヶ月程度で停止するためいろいろ調べていたら
    SDカードに書き込みが多いのが原因との記事が多数あったので実施してみました。
    効果についてはこれから検証します。
    なお、自作のプログラムについてもファイルはramdiskに書き出すものとする

     

    ■swapを無効化
        
        ○スワップを確認
        
        free -h
                          total        used        free      shared  buff/cache   available
            Mem:          926Mi        49Mi       657Mi       6.0Mi       218Mi       816Mi
        →    Swap:          99Mi          0B        99Mi
        swapで約100Mバイトってなってる
        
        ○swapを無効化
        
        sudo swapoff --all
        
        ○再度スワップを確認
        
        free -h
        
                          total        used        free      shared  buff/cache   available
            Mem:          926Mi        49Mi       657Mi       6.0Mi       219Mi       817Mi
        →    Swap:            0B          0B          0B
        swapは0バイトってなった
        
        ○でもこのままだと再起動で戻ってしまうそうなので dphys-swapfile を削除すれば良いとの事なので
        
        sudo apt-get remove dphys-swapfile
        

    ■RAMディスクの作成
        
        用語に慣れていないんだけどtmpfsってするとメモリ内に取ってくれるんだって。
        
        ○fstabを編集
        
            sudo vi /etc/fstab
            
                proc            /proc           proc    defaults          0       0
                PARTUUID=6c586e13-01  /boot           vfat    defaults          0       2
                PARTUUID=6c586e13-02  /               ext4    defaults,noatime  0       1
                # a swapfile is not a swap partition, no line here
                #   use  dphys-swapfile swap[on|off]  for that
            →    tmpfs           /tmp            tmpfs   defaults,size=200m 0       0
            →    tmpfs           /var/tmp        tmpfs   defaults,size=20m 0       0
            →    tmpfs           /var/log        tmpfs   defaults,size=200m 0       0
            →の行を追加
        
        ○再起動
        
            sudo reboot
        
        ○再移動後ログインして dfコマンドでマウント位置を確認
        
            df -h
                ファイルシス   サイズ  使用  残り 使用% マウント位置
                /dev/root         29G  1.3G   26G    5% /
                devtmpfs         459M     0  459M    0% /dev
                tmpfs            464M     0  464M    0% /dev/shm
                tmpfs            464M  6.2M  457M    2% /run
                tmpfs            5.0M  4.0K  5.0M    1% /run/lock
                tmpfs            464M     0  464M    0% /sys/fs/cgroup
            →    tmpfs             200M  144K   200M    1% /var/log
            →    tmpfs             200M     0   200M    0% /tmp
            →    tmpfs             16M     0   16M    0% /var/tmp
                /dev/mmcblk0p1   253M   52M  201M   21% /boot
                tmpfs             93M     0   93M    0% /run/user/1000
            tmpfsってなっているのでOKと思われ。
        
        ○/var/log/messagesの中身を表示してみる
        
            cat messages | more
            
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] Booting Linux on physical CPU 0x0
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] Linux version 4.19.75-v7+ (dom@buildbot) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1270 SMP
                 Tue Sep 24 18:45:11 BST 2019
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] CPU: div instructions available: patching division code
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] OF: fdt: Machine model: Raspberry Pi 3 Model B Rev 1.2
                Oct 19 13:21:56 raspberrypi kernel: [    0.000000] Memory policy: Data cache writealloc
            
                略
            
            起動ログがちゃんと出ているみたいなのでOKとする。
        
        ○/var/logの中に必要なディレクトリを自動で作るように/etc/rc.localに以下を追加する

     

            これをやっておかないとここを使うプログラムが死ぬ場合があるとのこと
            追加する場所はexitの手前
        
            sudo vi /etc/rc.local
            
                mkdir -p /var/log/apt
                mkdir -p /var/log/fsck
                mkdir -p /var/log/ntpstats
                mkdir -p /var/log/samba

                chmod 750 /var/log/samba
                chown ntp:ntp /var/log/ntpstats
                chown root:adm /var/log/samba

                touch /var/log/btmp
                touch /var/log/lastlog
                touch /var/log/wtmp

                chmod 600 /var/log/btmp
                chmod 664 /var/log/lastlog
                chmod 664 /var/log/wtmp

                chown root:utmp /var/log/btmp
                chown root:utmp /var/log/lastlog
                chown root:utmp /var/log/wtmp

                exit 0
        
        ○ログの出力を抑制する
        
            sudo vi /etc/rsyslog.conf
        
                以下の行をコメントにする
                
                #daemon.*                       -/var/log/daemon.log
                #kern.*                         -/var/log/kern.log
                #lpr.*                          -/var/log/lpr.log
                #mail.*                         -/var/log/mail.log
                #user.*                         -/var/log/user.log

                #mail.info                      -/var/log/mail.info
                #mail.warn                      -/var/log/mail.warn
                #mail.err                       /var/log/mail.err

                #news.crit                      /var/log/news/news.crit
                #news.err                       /var/log/news/news.err
                #news.notice                    -/var/log/news/news.notice

                #*.=debug;¥
                #       auth,authpriv.none;¥
                #       news.none;mail.none     -/var/log/debug
        
        ○ext4ジャーナルシステムのジャーナル機能を無効化
        
            $ sudo umount /dev/mmcblk0p2
            $ sudo tune2fs -O ^has_journal /dev/mmcblk0p2
            
            ※umountの時に何かプログラムを走らせていたりするとエラーになるので
             プログラムは止めたほうがいい
        
        ○バックアップ

     

            ramdiskの内容は電源を切ると消えてしまうので 一日1回程度の頻度で
            圧縮して保管しておくとよいと思われ。
            
            以下のコマンドをcrontabに仕込んでおく
                
                sudo tar cvzf /home/pi/log`date '+%Y%m%d%H%M'`.tgz /var/log/*
                
            以下の削除の仕組みもcrontabに仕込んでおく
                
                find /home/pi/log* -mtime +31  -exec rm -f {} ¥;

     

        ○書き込まれていない事の確認

     

            それで、いちおう もうSDカードに書いていないことを確認してみる。
            
                sudo find / -mmin -1 
                
                とかやって直近のファイル更新を見てみると
                たくさん出てくる。/proc/配下とか/sys/配下とか
                で調べると/proc/とか/sys/は実際にはメモリーなので、
                「| grep -v /proc」 とかとかを付け加えて
                最終的にこうなった
                
                sudo find / -mmin -1 | grep -v "/proc/" | grep -v "/sys/" | grep -v "/dev/" | grep -v "/tmp/" | grep -v "/var/" | grep -v "/run/"
                
                実行結果
                    find: `/proc/4261/task/4261/fd/5': そのようなファイルやディレクトリはありません
                    find: `/proc/4261/task/4261/fdinfo/5': そのようなファイルやディレクトリはありま せん
                    find: `/proc/4261/fd/5': そのようなファイルやディレクトリはありません
                    find: `/proc/4261/fdinfo/5': そのようなファイルやディレクトリはありません

                「ありません」 の行は無視していいと思われなので、直近の更新はメモリだけとなりました。
        
            再起動直後はこうなっていた
            
                sudo find / -mmin -3 | grep -v "/proc/" | grep -v "/sys/" | grep -v "/dev/" | grep -v "/tmp/" | grep -v "/var/" | grep -v "/run/"
                実行結果
                    find: `/proc/947/task/947/fd/5': そのようなファイルやディレクトリはありません
                    find: `/proc/947/task/947/fdinfo/5': そのようなファイルやディレクトリはありませ ん
                    find: `/proc/947/fd/5': そのようなファイルやディレクトリはありません
                    find: `/proc/947/fdinfo/5': そのようなファイルやディレクトリはありません
                    /etc/resolv.conf
                    /etc/fake-hwclock.data
                    /dev
                    /tmp
                    /run
                    /home/pi/.bash_history
                    /home/pi/.uim.d/fep
                
            ふーん。再起動ではファイルにはあんま書き込みしないのねーなんて思いながら・・・
            
            一応分析すると
                /dev /tmp /runはメモリなのでOKです
                /etc/resolv.conf : DHCPからもらったDNSを書き込んだようです
                /etc/fake-hwclock.data : NTPからもらった時間を書き込んだようです
                /home/pi/.bash_history : ログインしてコマンド入力した時にhistoryに記録されたようです
                /home/pi/.uim.d/fep   : ディレクトリですね。中身は空っぽです。
                              コンソールで日本語を扱いたかったのでuimとuim-anthyをインストールしたせいでしょうか。
                              いずれにしても、/home/pi配下の隠しファイルなのでユーザーに起因するものであり、
                              ログインさえしなければSDカードに書き込む事はないとおもわれます。
            
            あとは起動時に作成されて、起動後不要になったら消すといった使われ方をされているとfindでは見つかりませんね。


    RaspberryPi Jessie Lite コンソールで日本語を使えるようにする

    0

      RaspberryPi Jessie Lite コンソールで日本語を使えるようにする

       

      RaspberryPi Jessie Lite のコンソールではデフォルトで日本語が使えない。

      なので、日本語が表示できる様にするまでの手順をまとめてみた。

       

      ネットワーク設定(ネットワークが既につながっている場合は不要)

          sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

              country=GB
              ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
              update_config=1
          →    network={
          →        ssid="あなたのSSID"
          →        psk="あなたのパスワード"
          →    }
          
          →を追加
          
          sudo reboot
          
          ネットワークにつながるようになる。
          
      ロケールやキーボードの設定(いちおう見直してもらうといいと思います)
          
          sudo raspi-config

              →4 Localisation Options
                  →I1 Change Locale
                      →ja_JP.UTF-8 UTF-8
                  →I2 Change Timezone
                      →Asia
                          →Tokyo
                  →I3 Change Keyboard Layout
                      →Advanced 105 keyboard
                          →Japanese(OADG 109A)
                              →default
                                  →none composekey
              ※ご自分のキーボードに合わせて設定してください。

       

      ※こっから先が本番

       

      日本語フォントインストール

          sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfonts-kaname


      日本語メソッドをインストール

          sudo apt-get install uim uim-anthy

       

      日本語ターミナルをインストール

          sudo apt-get install jfbterm

          ここまでやると「jfbterm」を起動することで
          日本語表示が可能になるらしい。

       

      さらに これを自動的に行う様にbash.rcに仕掛けを行う

          vi ~/.bashrc

              省略
              # If this is an xterm set the title to user@host:dir
              case "$TERM" in
              xterm*|rxvt*)
                  PS1="¥[¥e]0;${debian_chroot:+($debian_chroot)}¥u@¥h: ¥w¥a¥]$PS1"
                  ;;
              *)
                  ;;
              esac
              省略

          これの「*)」の行の前に記述を追加

              # If this is an xterm set the title to user@host:dir
              case "$TERM" in
              xterm*|rxvt*)
                  PS1="¥[¥e]0;${debian_chroot:+($debian_chroot)}¥u@¥h: ¥w¥a¥]$PS1"
                  ;;
          →    linux)
          →        if [ -c /dev/fb0 ]; then
          →            jfbterm -q -e uim-fep -u anthy
          →            exit
          →        fi
          →        ;;
              *)
                  ;;
              esac

          →を追加
       


      raspberrypi rsyslogd-2007: action 'action 17' suspended, next retry 対応

      0

        raspberrypi rsyslogd-2007: action 'action 17' suspended, next retry 対応

         

        ■Raspberry pi を使用していると謎のエラーが頻繁に出力されるようになる件の対応

         

        /var/log/messagesに「raspberrypi rsyslogd-2007: action 'action 17' suspended, next retry」が頻繁に出力されるようになったので対策します。
        これはDEBIAN由来のバグとの事です。

         

            ○rsyslog.confを編集。

         

                sudo vi /etc/rsyslog.conf

         

                以下をコメント
                #daemon.*;mail.*;¥
                #   news.err;¥
                #   *.=debug;*.=info;¥
                #   *.=notice;*.=warn   |/dev/xconsole


         


        raspberry piカーネルパニックで再起動。

        0

          raspberry piカーネルパニックで再起動。

           

          機種:raspberry pi 3B
          OS:raspbian jessie lite

           

          ■設定を入れる

              sudo vi /etc/sysctl.conf
              
                  kernel.panic = 10
                  
                  一番下に入れる。
                  カーネルパニック後10秒で再起動

           

          ■設定を反映
                  
              sudo sysctl -p

           

          ■設定を確認
              
              sysctl kernel.panic
           

          ■テスト

           

           sudo su - root

           cat /proc/sys/kernel/panic

           

           ちゃんと再起動してくる

           

           

           


          raspberry piのmessagesに「Oct 21 06:25:05 raspberrypi rsyslogd: [origin software="rsyslogd" swVersion="8.4.2" x-pid="445" x-info="http://www.rsyslog.com"] rsyslogd was HUPed」と書かれていたので調べてみました。

          0

            raspberry piのmessagesに「Oct 21 06:25:05 raspberrypi rsyslogd: [origin software="rsyslogd" swVersion="8.4.2" x-pid="445" x-info="http://www.rsyslog.com"] rsyslogd was HUPed」と書かれていたので調べてみました。

             

            機種:raspberry pi 3b
            OS:raspbian jessie lite

             

            最近ラズパイの監視をするようになって/var/log/messagesの中身に関心がありまして
            本日以下のメッセージが出ていたいので調べてみた


            「Oct 21 06:25:05 raspberrypi rsyslogd: [origin software="rsyslogd" swVersion="8.4.2" x-pid="445" x-info="http://www.rsyslog.com"] rsyslogd was HUPed」

             

            英語のページで
            https://www.raspberrypi.org/forums/viewtopic.php?t=37751

            ばっちりなページを見つけたので転載しておきます。

            原文
            「The signal is sent by logrotate (see "postrotate" in /etc/logrotate.d/rsyslog). It is to tell rsyslogd to stop writing to the old log files that have now been renamed.」

            翻訳
            「信号はlogrotateによって送信されます(/etc/logrotate.d/rsyslogの「postrotate」を参照)。名前を変更した古いログファイルへの書き込みを停止するようrsyslogdに指示します」

            すごい判りやすいよーん

            実際/var/log/syslogのファイルが同時刻にローテーションされていました。
             


            raspberry pi のログになんか/dev/ttyS0からのログインでエラーになっているログがたくさん出ていたので対策

            0

              raspberry pi のログになんか/dev/ttyS0からのログインでエラーになっているログがたくさん出ていたので対策

               

              機種:raspberry pi3B
              OS:Raspbian JESSIE Lite

               

              ■ある日ログを見ていたら以下のようなメッセージが繰り返し出ておりましたので対策してみた。

               

              Oct 21 10:47:57 raspberrypi login[1312]: FAILED LOGIN (1) on '/dev/ttyS0' FOR 'UNKNOWN', Authentication failure
              Oct 21 10:47:57 raspberrypi login[1312]: pam_securetty(login:auth): unexpected response from failed conversation function
              Oct 21 10:47:57 raspberrypi login[1312]: pam_securetty(login:auth): cannot determine username
              Oct 21 10:48:00 raspberrypi login[1312]: FAILED LOGIN (2) on '/dev/ttyS0' FOR 'UNKNOWN', Error in service module
              Oct 21 10:48:01 raspberrypi login[1312]: pam_securetty(login:auth): unexpected response from failed conversation function
              Oct 21 10:48:01 raspberrypi login[1312]: pam_securetty(login:auth): cannot determine username
              Oct 21 10:48:04 raspberrypi login[1312]: FAILED LOGIN (3) on '/dev/ttyS0' FOR 'UNKNOWN', Error in service module
              Oct 21 10:48:04 raspberrypi login[1312]: pam_securetty(login:auth): unexpected response from failed conversation function
              Oct 21 10:48:04 raspberrypi login[1312]: pam_securetty(login:auth): cannot determine username
              Oct 21 10:48:07 raspberrypi login[1312]: FAILED LOGIN (4) on '/dev/ttyS0' FOR 'UNKNOWN', Error in service module
              Oct 21 10:48:07 raspberrypi login[1312]: pam_securetty(login:auth): unexpected response from failed conversation function
              Oct 21 10:48:07 raspberrypi login[1312]: pam_securetty(login:auth): cannot determine username
              Oct 21 10:48:10 raspberrypi login[1312]: FAILED LOGIN (5) on '/dev/ttyS0' FOR 'UNKNOWN', Error in service module
              Oct 21 10:48:10 raspberrypi login[1312]: TOO MANY LOGIN TRIES (5) on '/dev/ttyS0' FOR 'UNKNOWN'
              Oct 21 10:48:10 raspberrypi login[1312]: pam_mail(login:session): cannot determine username
              Oct 21 10:48:10 raspberrypi login[1312]: pam_unix(login:session): close_session - error recovering username
              Oct 21 10:48:13 raspberrypi login[1329]: pam_unix(login:auth): check pass; user unknown
              Oct 21 10:48:13 raspberrypi login[1329]: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty=/dev/ttyS0 ruser= rhost=

              ■対処1
              sudo systemctl stop serial-getty@ttyAMA0.service
              sudo systemctl disable serial-getty@ttyAMA0.service
              sudo reboot

               

              ■対処2
              sudo raspi-config
                  
                  →5 Interfacing Options
                      →P6 Serial
                          →Would you like a login shell to be accessible overserial?
                            いいえ
                          →Would you like the serial port hardware to be enabled?
                            はい
                              The serial login shell is disabled
                              The serial interface is enabled
                              了解
                          →reboot now

               

              上記の対処の対処2が効いたまたは両方で効いた。→後日談。対処1はシリアルの名前が間違っている。


              おそらくはセットアップ時raspi-configで
              「Would you like a login shell to be accessible overserial?」のメッセージに何も考えずに「はい」としたせいだと思われ。
              翻訳すると「ログインシェルにオーバーシリアルでアクセスできるようにしますか?」となり。
              つまり、ラズパイのシリアルコンソールを有効にするってことで、
              今回の自分のシステム(非公開)のようにシリアルから何か読み込むシステムの場合は上記のように最初の質問に「いいえ」と答えて、
              次の質問「シリアルポートハードウェアを有効にしますか?」に「はい」と答える必要があるって事ですね。
               


              金属の棒を使用した水検知センサー タミヤ グレードアップパーツシリーズ GP.416 60mm ブラック強化シャフト (4本) 

              0

                金属の棒を使用した水検知センサー タミヤ グレードアップパーツシリーズ GP.416 60mm ブラック強化シャフト (4本) 

                 

                昔何かの為に買ったタミヤの金属の棒
                たぶん「タミヤ グレードアップパーツシリーズ GP.416 60mm ブラック強化シャフト (4本) 15416」

                 


                金属ならなんでもOKですが、
                これを使用して水にくっついたのを検知するセンサーを作成します。

                 

                 

                ■回路図

                 

                 

                ■プログラム

                 

                const int LED = 13;
                const int SENSOR = 7;

                void setup() {
                  pinMode(LED, OUTPUT);
                  pinMode(SENSOR, INPUT);
                }

                void loop() {
                  int val = digitalRead(SENSOR);
                  if( val == HIGH ){
                    digitalWrite(LED, HIGH);
                  }
                  else{
                    digitalWrite(LED, LOW);
                  }
                }


                ■解説


                回路図で緑で囲った部分がセンサーになります。
                「SENSOR1」と「SENSOR2」の両方を水につけた場合にLEDが点灯する様にします。
                水は電気を通すことから、センサーの端子の間に電気が流れた事を検知すれば良い事になります。
                単純にスイッチと認識してもよいかもしれません。
                SENSOR2は通常1MΩの抵抗を通じてGNDに接続していますのでATMEGAのD7端子は0V(LO)になります。
                SENSOR1とSENSOR2が直接接触した場合(電気が流れた場合)はDC3.3Vに直結されるためにATMEGAのD7端子は3.3V(HIGH)になります。
                水の場合でも電気が流れますが、抵抗がありますので水の場合はATMEGAのD7端子は2.3VぐらいになりますがATMEGAはHIGHと認識します。

                プログラムは単純に7番ピンからにセンサーの値を入手、
                HIGHかを判定してHIGHだったらLEDを点灯します。

                 

                JUGEMテーマ:電子工作


                yolo3でオリジナルデータの学習にチャレンジする。(labelimgによるアノテーションファイルの作成)

                0

                  yolo3でオリジナルデータの学習にチャレンジする。(labelimgによるアノテーションファイルの作成)

                   

                  JUGEMテーマ:電子工作


                  顔の学習に成功して気を良くしたので今度はオリジナルデータの作成をしてみたいと思います。
                  学習してもらうのは招き猫これです。

                   


                  クラスは1つなのでクラスの番号は0で名前はmanekinekoとします。

                  アノテーション作成支援ツールの labelimg を活用してyolo3の学習データを作成して学習する事例です。
                   

                  参考ページ
                  https://haitenaipants.hatenablog.com/entry/2018/06/09/235950
                  いつもありがとうございます。


                  ■必要なもの

                   

                  python 3.6
                  PyQt5
                  labelimg 

                   

                  ■環境

                   

                   Windows10
                   Anaconda

                   

                  ■Anacondaの環境を作成

                   

                  Anacondaを起動してEnvironments→Createをクリック
                  作成する環境の名前を入力
                   labelImg
                  作成したlabelImgという環境のTermialを開く

                   

                  ■PyQt5をインストール

                   

                  pip install PyQt5

                   

                  ・バージョンを表示してみる

                   

                  pyrcc5 -version

                  pyrcc5 v5.12

                   

                  ■labelimgのインストール

                   

                  ・githubから


                  https://github.com/tzutalin/labelImg
                  clone or download をクリックしてZIPをダウンロード

                   

                  ・ZIPを展開

                   

                   

                  ・展開したlabelImg-masterにcdする

                   

                  cd labelImg-master

                   

                  ・インストール?


                  pyrcc5 -o resources.py resources.qrc
                  何も表示されないがエラーにもならないのでOK?

                   

                  ■labelimgを起動

                   

                  python labelImg.py

                  エラーになる。
                  ModuleNotFoundError: No module named 'lxml'

                   

                  ■xmlのライブラリをインストール


                  参考ページ
                  https://techacademy.jp/magazine/19063

                   

                  pip install requests
                  pip install lxml

                   

                  ■labelimgを起動

                   

                  python labelImg.py

                   

                  ■画面が起動した。

                   


                  ■画面の使い方

                   

                  ・保存を自動化するためにメニュー View→AutoSaveModeにしておく
                  ・クラスは一つだけなのでメニュー View→SingleClassModeにしておく
                  ・OpenDirをクリックしてディレクトリ指定すると右下の所に一覧が出て
                   1枚目の画像が表示される
                  ・yoloの形式で出力する場合は左側のPascalVOC⇔YOLOの切り替えボタンでYOLOにしておく
                  ・保存すると該当のディレクトリにclasses.txtが出来るんですがプログラムと連携できてないようで。
                   多分バグでしょう。
                  ・右上のUser default labelをチェックしてラベルを付けておくclassが一つの場合はdogにしちゃう。
                   そうすれば自動的にclassは0になって作成される。
                  ・wを押して該当の部分(□)をマウスでドラッグして指定する
                  ・dを押して(自動保存して)次のファイルへ移る
                  ・aを押すと前のファイルへ移る

                   


                  ■その他のコマンド


                  参考
                  http://demura.net/misc/14350.html

                  Ctrl + u     ディレクトリからすべての画像ファイルを読み込む
                  Ctrl + r     アノテーションのディレクトリを変更
                  Ctrl + s     保存
                  Ctrl + d     現在のラベルと矩形をコピー
                  Space     現在の画像を検証したとフラグをつける
                  w     矩形の生成
                  d     次の画像
                  a     前の画像
                  del     選択した矩形の消去
                  Ctrl++     ズームイン
                  Ctrl?     ズームアウト
                  ↑→↓←     矢印キー:選択した矩形の移動


                  ■labelImg使って招き猫のデータを効率よく作成

                   

                   使用した画像数は118
                   labelimgで指定した矩形の数は約350
                   所要時間は2時間ぐらいかな。
                   肩コッタ。

                   

                  結果的にubuntuのdarknet配下に以下の様に配置

                   

                  ※ここから先は前の記事※http://miha.jugem.cc/?eid=207で作った
                   ubuntu上での操作になります。

                   

                  darknet
                  ├── manekineko
                  │    ├── classes.txt
                  │    ├── DSC_0001.JPG
                  │    ├── DSC_0001.txt
                  │    ├── DSC_0002.JPG
                  │    ├── DSC_0002.txt
                  │    ├── DSC_0003.JPG
                  │    ├── DSC_0003.txt
                   省略
                  │    ├── DSC_0118.JPG
                  │    ├── DSC_0118.txt
                  │    ├── test.txt
                  │    └── train.txt
                  ├── cfg
                  │    ├── manekineko.data
                  │    ├── manekineko.names
                  │    └── yolov3.cfg
                  └── darknet53.conv.74

                   

                  ■test.txtの中身

                   

                      manekineko/DSC_0010.JPG
                      manekineko/DSC_0020.JPG
                      manekineko/DSC_0030.JPG
                      manekineko/DSC_0040.JPG
                      manekineko/DSC_0050.JPG
                      manekineko/DSC_0060.JPG
                      manekineko/DSC_0070.JPG
                      manekineko/DSC_0080.JPG
                      manekineko/DSC_0090.JPG
                      manekineko/DSC_0100.JPG
                      manekineko/DSC_0115.JPG

                   

                  ■train.txtの中身

                   

                      manekineko/DSC_0001.JPG
                      manekineko/DSC_0002.JPG
                      manekineko/DSC_0003.JPG
                      省略
                      manekineko/DSC_0118.JPG
                  ※jpgファイルは全部で118その中で11をtest.txt、残りの107をtrain.txtにする


                  ■manekineko.dataの中身


                      classes = 1
                      train  = manekineko/train.txt
                      valid  = manekineko/test.txt
                      names = cfg/manekineko.names
                      backup = backup/
                      
                  ■manekineko.namesの中身

                   

                      manekineko

                   

                  ■yolov3.cfgの中身

                   

                   classesは顔の時と同じ1なので、yolov3.cfgは前の記事と変更なし
                    →前の記事※http://miha.jugem.cc/?eid=207

                   

                  ■darknet53.conv.74の中身

                   

                   https://pjreddie.com/media/files/darknet53.conv.74
                   から持ってくる。顔の時と同じ

                   

                  ■学習

                   

                      ./darknet detector train cfg/manekineko.data cfg/yolov3.cfg darknet53.conv.74

                    
                  ・翌朝

                   

                   avg lossの数字を確認すると0.061
                   すごい低い値になっていました。

                   

                  backupの中のyolov3_last.weightsファイルを取り出す。

                   

                  ■chainer+yolo3で顔認識

                   

                  ※ここから先はいつも使っているwindows10+anacondaの環境での操作になります。
                   参考記事はhttp://miha.jugem.cc/?eid=189とhttp://miha.jugem.cc/?eid=190

                   

                  □chainerで読み込めるnpzの形式に変更する

                   

                  copy yolov3_last.weights yolo3-manekineko_final.weights
                  python darknet2npz.py --model yolo_v3 --n-fg-class 1 yolo3-manekineko_final.weights yolo3-manekineko_final.weights.npz

                   

                  □classの一覧ファイルの作成

                   

                  yolo3-manekineko.list
                  以下の内容で作成

                  manekineko

                   

                  □実行!!

                   

                  python yolo3.py --pretrained-model yolo3-manekineko_final.weights.npz --class_num 1 --class_list yolo3-manekineko.list 0


                  □実行結果

                   


                  100%で認識しています。
                  こういった人などに比べて単純なものは120枚の画像で350矩形の学習ぐらいでも結構大丈夫みたいです。

                   

                   


                  顔の学習と認識できるかな 成功!!

                  0

                    顔だけ認識したいという場合に顔の学習済みモデルが有れば
                    それを使用すれば済むんですが、いろいろ探したけど
                    見つからないか見つかったけどchainerで使える拡張子npzに
                    変換する時にエラーになったりして色々駄目だったので
                    試行錯誤しつつなんとか出来たのでその時の記録。

                     

                    参考ページ
                    https://qiita.com/nakamura21/items/2b2ff6524710d167d618
                    いつもすいません。

                     

                    ■Ubuntuのインストール

                     

                     Ubuntu18.4.2Lをまっさらな状態でインストール
                     & インストール中に最新化するか聞かれるので最新化する。

                     マシンのスペック
                      Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz
                      メモリ16Gバイト
                      GeForce GT 1030

                     

                    ■ドライバーのインストール

                     

                     sudo ubuntu-drivers autoinstall
                     sudo reboot

                     

                     なんかグラボを付けている状態で
                      sudo ubuntu-drivers autoinstall ってすると
                     自動でドライバーが入るそうで。なんかすげー
                     っていうかWindowsではこれ常識か。

                     

                    ■グラボ認識しているか表示

                     

                     nvidia-smi

                     

                    ■CUDAのインストール

                     

                     sudo apt install nvidia-cuda-toolkit nvidia-driver-390
                     sudo reboot

                     

                    ■cuDNNのダウンロードとインストール

                     

                     NVIDIAさんのページから持ってくる。
                     アカウント作ってログインする必要がある。

                     

                     https://developer.nvidia.com/rdp/cudnn-archive

                     

                     参考ページではcuDNN v7.1.2 (Mar 21, 2018), for CUDA 9.1 & 9.2ってなっているけど
                     mac用しかない。

                     適当に入れるといつものように悪い事が起きそうなので
                     nvcc -Vでcudaのバージョンを調べる

                     

                     nvcc -V
                     nvcc: NVIDIA (R) Cuda compiler driver
                     Copyright (c) 2005-2017 NVIDIA Corporation
                     Built on Fri_Nov__3_21:07:56_CDT_2017
                     Cuda compilation tools, release 9.1, V9.1.85

                     

                     ※ 9.1な模様 

                     

                     9.1対応のを探して
                      Download cuDNN v7.1.3 (April 17, 2018), for CUDA 9.1
                     の
                      cuDNN v7.1.3 Library for Linux
                     をダウンロード


                     本当はUbuntu18.4用のを探したんだけどCuda9.1のはコレだったので。
                     あとでdarknetコンパイルするときにMakefileを変更する必要がある。

                     

                    □展開

                     

                     tar xzvf cudnn-9.1-linux-x64-v7.1.tgz

                     

                     展開後のファイルの構成


                     cuda
                     ├── NVIDIA_SLA_cuDNN_Support.txt
                     ├── include
                     │   └── cudnn.h
                     └── lib64
                         ├── libcudnn.so -> libcudnn.so.7
                         ├── libcudnn.so.7 -> libcudnn.so.7.1.3
                         ├── libcudnn.so.7.1.3
                         └── libcudnn_static.a

                     

                    □インストール

                     

                     sudo cp -a cuda/include/* /usr/lib/cuda/include/
                     sudo cp -a cuda/lib64/* /usr/lib/cuda/lib64/

                     

                     vi ~/.bashrc

                     以下を追加


                     ## CUDA and cuDNN paths
                     export PATH=/usr/lib/cuda/bin:${PATH}
                     export LD_LIBRARY_PATH=/usr/lib/cuda/lib64:${LD_LIBRARY_PATH}

                     

                    □後片付け
                     
                     sudo apt autoremove
                     sudo apt clean

                     

                    □.bashrcを変更したのでterminalに反映

                     ここで今までっ使っていたterminalを閉じて
                     新しいterminalを起動

                     

                    ■DARKNETの入手とインストール

                     

                    □gitをインストール

                     

                     sudo apt install git

                     

                    □DARKNETをインストール

                     

                     git clone https://github.com/AlexeyAB/darknet.git

                     cd darknet

                     

                    ■DARKNETのコンパイル


                     vi Makefile
                     以下の箇所を修正


                      GPU=1
                      CUDNN=1

                     

                     make

                     

                     →エラーになる

                     

                    □Makefileをubuntuに合わせて変更

                     

                     COMMON+= -DGPU -I/usr/local/cuda/include/
                       ↓
                     COMMON+= -DGPU -I/usr/lib/cuda/include
                     
                     LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
                       ↓
                     LDFLAGS+= -L/usr/lib/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
                     
                     CFLAGS+= -DCUDNN -I/usr/local/cudnn/include
                       ↓
                     CFLAGS+= -DCUDNN -I/usr/lib/cuda/include
                     
                     LDFLAGS+= -L/usr/local/cudnn/lib64 -lcudnn
                       ↓
                     LDFLAGS+= -L/usr/lib/cuda/lib64 -lcudnn
                     
                     make
                     
                     今度はうまく行ったっぽい。
                     
                    □DARKNETの起動を確認
                     
                     ./darknet 
                     usage: ./darknet <function>

                     

                     よしよし。
                     ここまでOKか

                     

                    ■学習用のデータセットの準備

                     

                    ここで再度先日の参考ページ登場
                    https://qiita.com/ha9kberry/items/1bc113cfcd9892a9ddbd
                    ほんと助かっています。


                    前回は01のデータセット準備までは出来ているはずなので。
                    と思ったんだけど。
                    圧縮ファイルがぶっ壊れてた。涙;;
                     →やり直す。やり直し部分も含めて以下へ記載しています。

                     

                    ■顔の学習の元になる顔の写真と顔の座標のファイルを整備

                     

                    学習させるには顔の写真と、その写真の中の何処が顔なのかを入力する必要があり。
                    その元になるファイルはいろんなサイトで公開してもらっているようなので
                    これを使用する。

                     

                    □顔の学習のもとになる顔の写真と顔の座標のファイルをダウンロード

                     

                    http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/

                     

                    WIDER Face Training Images
                     と
                    Face annotations


                    をダウンロードして解凍する

                    こんな感じで展開されます
                    .
                    ├── WIDER_train
                    │   └── images
                    │       ├── 0--Parade
                    │       │   ├── 0_Parade_Parade_0_1014.jpg
                    │       │   ├── 0_Parade_Parade_0_1019.jpg
                    │       │   ├── 0_Parade_Parade_0_1040.jpg
                    │       │   ├── 0_Parade_Parade_0_1041.jpg
                      省略
                    │       ├── 1--Handshaking
                    │       │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │       │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │       │   ├── 1_Handshaking_Handshaking_1_113.jpg
                     省略
                    │           ├── 9_Press_Conference_Press_Conference_9_944.jpg
                    │           ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │           └── 9_Press_Conference_Press_Conference_9_97.jpg
                    ├── wider_face_split
                        ├── readme.txt
                        ├── wider_face_test.mat
                        ├── wider_face_test_filelist.txt
                        ├── wider_face_train.mat
                        ├── wider_face_train_bbx_gt.txt
                        ├── wider_face_val.mat
                        └── wider_face_val_bbx_gt.txt

                     

                    中を見ると集合写真とかのjpgが沢山と
                     wider_face_train_bbx_gt.txtが顔の座標が入っている模様。

                     

                    □Annotationファイル作成の環境整備

                     

                    参考ページの人はJupyter Notebookを使用しているようなんですが
                    自分は違うので自分で環境整備します。

                     

                    sudo apt install python3
                    sudo apt install python3-pip
                    pip3 install opencv-python

                     

                    □Annotationファイルを作成する前にファイルを整理する

                     

                    vi generator.py
                    以下の内容で作成

                     

                    import os
                    import cv2
                    import math
                    import random

                    txt_file = 'wider_face_split/wider_face_train_bbx_gt.txt'
                    with open(txt_file) as f:
                        num = f.read().count('jpg')
                    print('number of images:',num)

                     

                    そのまま実行すると


                    python3 generator.py 
                    number of images: 12880


                    となるんです。参考ページの結果は5451。

                     

                    参考ページによるとなんでかはわかりませんけど
                    「予め0--Parade?20--Family_Groupのみ抽出」となっていますんで

                     

                    wider_face_train_bbx_gt.txtを開いて
                    0--Parade?20--Family_Groupだけ残す。

                     

                    ちなみに、このファイルの番号が曲者で
                    普通に20--Family_Groupの後ろを削除すればOKと思うじゃないですか?
                    しかーし、よく見ると
                    20--Family_Groupのあとには21--Festival/21_Festival_Festival_21_14.jpgが有って
                    その後ろは22→23→・・・・と続きますが
                    29の次が3--Riot/3_Riot_Riot_3_189.jpgになるので注意です。

                     

                    それと、もう一つ。
                    Ubuntuに最初から入っていたテキストエディターなんですが、
                    これでやると、セーブしたときにファイルが崩れます。
                    適当に他の行とくっついて以下のような行が発生して後ろの工程でエラーになりますので注意です。
                    「264--Dancing/4_Dancing_Dancing_4_71.jpg」

                     

                    もう一回実行

                     

                    python3 generator.py
                    number of images: 5451

                     

                    参考ページと同じでok

                     

                    □解説 Annotationファイルの構成

                     

                    0_Parade_marchingband_1_45.txt


                    0 0.68017578125 0.9162995594713657 0.0400390625 0.07342143906020558
                    0 0.02978515625 0.8127753303964758 0.0185546875 0.027900146842878122

                     

                    - 各バウンディングボックスごとにクラス x座標 y座標 ボックス幅 ボックス高さ
                    - 座標はバウンディングボックスの中心座標
                    - 座標、幅・高さともに、画像の幅・高さに対する相対値
                    - Annotationファイルは、画像ファイルと同じディレクトリ内に保存

                     

                    上記の形式になるように変換する。

                    その為のプログラムは参考ページを参考に作成する。

                     

                    □変換プログラム

                    vi generator2.py

                    以下の内容で作成

                     

                    import cv2

                    def generator():
                        num = 5451
                        with open("wider_face_train_bbx_gt.txt") as f:
                            img_paths=[]

                            for i in range(num):
                                # 両端の空白や改行を除去して1行ずつ読み込む
                                img_path=f.readline().strip()
                                # 画像パス一覧取得
                                img_paths.append(img_path)
                                # 画像を読み込み幅・高さ取得
                                im = cv2.imread(img_path)
                                im_h, im_w, im_c = im.shape
                                # '/'で分割
                                split=img_path.split('/')
                                # Annotationファイルを格納するディレクトリ取得
                                dir_name=split[0]
                                # Annotationファイル名作成
                                file_name=split[1].replace('.jpg', '.txt')
                                # ボックス数取得
                                count = int(f.readline())
                                readline=[]
                                readlines=[]

                                for j in range(count):
                                    readline=f.readline().split()
                                    # ボックスの左上座標を取得
                                    xmin=int(readline[0])
                                    ymin=int(readline[1])
                                    # ボックスの幅・高さを取得
                                    w=int(readline[2])
                                    h=int(readline[3])
                                    # ボックスの中央座標(相対値)を作成
                                    xcenter=str((xmin+w/2)/im_w)
                                    ycenter=str((ymin+h/2)/im_h)
                                    # ボックスの幅・高さを相対値に変換
                                    w=str(w/im_w)
                                    h=str(h/im_h)

                                    class_num='0'
                                    # クラス x座標 y座標 ボックス幅 ボックス高さを半角スペースで結合
                                    string=' '.join([class_num, xcenter, ycenter, w, h])
                                    readlines.append(string)
                                # 改行で結合    
                                readlines_str='¥n'.join(readlines)
                                # 該当するディレクトリ内にAnnotationファイルを保存
                                with open(dir_name+'/'+file_name, 'w') as j:
                                    j.write(readlines_str)

                        # 画像パス一覧を出力
                        return img_paths

                    img_paths = generator()

                     

                    これを動かすのにディレクトリ構成を以下のように変更

                    .
                    ├── 0--Parade
                    │   ├── 0_Parade_Parade_0_1014.jpg
                    │   ├── 0_Parade_Parade_0_1019.jpg
                    │   ├── 0_Parade_Parade_0_1040.jpg
                     省略
                    ├── 1--Handshaking
                    │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   ├── 1_Handshaking_Handshaking_1_113.jpg
                     省略
                    │   ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │   └── 9_Press_Conference_Press_Conference_9_97.jpg
                    ├── generator2.py
                    └── wider_face_train_bbx_gt.txt

                     

                    そこで
                    python3 generator2.py を実行。

                     

                    実行すると、jpgファイルと同じディレクトリにjpg部分をtxtにしたファイルが作成される

                     

                    .
                    ├── 0--Parade
                    │   ├── 0_Parade_Parade_0_1014.jpg
                    │   ├── 0_Parade_Parade_0_1014.txt
                    │   ├── 0_Parade_Parade_0_1019.jpg
                    │   ├── 0_Parade_Parade_0_1019.txt
                    │   ├── 0_Parade_Parade_0_1040.jpg
                    │   ├── 0_Parade_Parade_0_1040.txt
                     省略
                    ├── 1--Handshaking
                    │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   ├── 1_Handshaking_Handshaking_1_102.txt
                    │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   ├── 1_Handshaking_Handshaking_1_105.txt
                    │   ├── 1_Handshaking_Handshaking_1_113.jpg
                    │   ├── 1_Handshaking_Handshaking_1_113.txt
                     省略
                    │   ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │   ├── 9_Press_Conference_Press_Conference_9_946.txt
                    │   ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │   └── 9_Press_Conference_Press_Conference_9_97.txt
                    ├── generator2.py
                    └── wider_face_train_bbx_gt.txt


                    □trainデータ、testデータそれぞれで使う画像のパス一覧テキストファイルを作成

                     

                    プログラムを見るとfaceというディレクトリの中のファイル一覧を取ってくるようになっているようなのと、
                    0--Parade?20--Family_Group以外が有るとうまく行かないようなんで
                    以下の構成に変更
                     21--Festival以降のフォルダーは削除

                    .
                    ├── face
                    │   ├── 0--Parade
                    │   │   ├── 0_Parade_Parade_0_1014.jpg
                    │   │   ├── 0_Parade_Parade_0_1014.txt
                    │   │   ├── 0_Parade_Parade_0_1019.jpg
                    │   │   ├── 0_Parade_Parade_0_1019.txt
                     省略
                    │   ├── 1--Handshaking
                    │   │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_102.txt
                    │   │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_105.txt
                     省略
                    │       ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │       └── 9_Press_Conference_Press_Conference_9_97.txt
                    ├── generator3.py
                    └── wider_face_split
                        └── wider_face_train_bbx_gt.txt

                     

                    ・trainingとtestに分けるプログラム

                     

                    vi generate3.py
                    以下の内容で作成

                     

                    import math
                    import glob

                    num = 5451
                    # testデータの比率
                    test_size=0.1
                    test_num=math.floor(num*test_size)
                    train_num=num-test_num
                    print('number of train images:', train_num)
                    print('number of test images:', test_num)

                    # 画像データを格納しているディレクトリ
                    img_paths=glob.glob("face/*/*.jpg")

                    # trainファイル作成
                    train_list=img_paths[:train_num]
                    train_str='¥n'.join(train_list)
                    with open('train.txt', 'w') as f:
                        f.write(train_str)

                    # testファイル作成
                    test_list=img_paths[train_num:]
                    test_str='¥n'.join(test_list)
                    with open('test.txt', 'w') as f:
                        f.write(test_str)

                     

                    ・実行


                     python generator3.py

                     

                    以下の様にtest.txtファイルとtrain.txtファイルができる

                     

                    test.txt
                    内容は以下の通り


                    face/2--Demonstration/2_Demonstration_Demonstration_Or_Protest_2_485.jpg
                    face/2--Demonstration/2_Demonstration_Political_Rally_2_190.jpg
                    face/2--Demonstration/2_Demonstration_Protesters_2_14.jpg
                    face/2--Demonstration/2_Demonstration_Political_Rally_2_469.jpg
                    省略

                     

                    train.txt
                    内容は以下の通り


                    face/16--Award_Ceremony/16_Award_Ceremony_Awards_Ceremony_16_325.jpg
                    face/16--Award_Ceremony/16_Award_Ceremony_Awards_Ceremony_16_82.jpg
                    face/16--Award_Ceremony/16_Award_Ceremony_Awards_Ceremony_16_538.jpg
                    face/16--Award_Ceremony/16_Award_Ceremony_Awards_Ceremony_16_41.jpg
                    省略

                     

                    ・結果的に以下のディレクトリ構成になる
                    .
                    ├── face
                    │   ├── 0--Parade
                    │   ├── 0--Parade
                    │   │   ├── 0_Parade_Parade_0_1014.jpg
                    │   │   ├── 0_Parade_Parade_0_1014.txt
                    │   │   ├── 0_Parade_Parade_0_1019.jpg
                    │   │   ├── 0_Parade_Parade_0_1019.txt
                     省略
                    │   │   ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │   │   ├── 9_Press_Conference_Press_Conference_9_946.txt
                    │   │   ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │   │   └── 9_Press_Conference_Press_Conference_9_97.txt
                     省略
                    ├── generator3.py
                    ├── test.txt
                    ├── train.txt
                    └── wider_face_split
                        └── wider_face_train_bbx_gt.txt

                     

                    ■02.Darknetで学習を実施。

                     

                    参考ページ
                    https://qiita.com/ha9kberry/items/e7c822dd0874e5a24639
                    ほんといつも助かっています。

                     

                    ここまでの操作でダークネットのインストールとコンパイルで成功しているので
                    その続きから行う。

                     

                    □weightをダウンロード

                     

                    wget https://pjreddie.com/media/files/darknet53.conv.74


                    □設定ファイル作成

                     

                    vi cfg/obj.data
                    以下の内容で作成

                     

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

                     

                    vi cfg/obj.name
                    以下の内容で作成

                     

                    face

                     

                    □設定ファイルの編集

                     

                    yolov3.cfg編集

                    vi cfg/yolov3.cfg


                    Line 3:コメントアウト
                    Line 4:コメントアウト
                    Line 6:batch=24に設定
                    Line 7:subdivisions=8に設定

                    ※変更箇所は「→」の所
                          1 [net]
                          2 # Testing
                    →    3 #batch=1
                    →    4 #subdivisions=1
                          5 # Training
                    →    6 batch=24
                    →    7 subdivisions=8
                          8 width=416
                          9 height=416
                         10 channels=3
                         11 momentum=0.9

                    filters=(classes+5)*3
                    Line 603:filters=18に設定
                    Line 610:classes=1に設定
                    Line 689:filters=18に設定
                    Line 696:classes=1に設定
                    Line 776:filters=18に設定
                    Line 783:classes=1に設定

                        599 [convolutional]
                        600 size=1
                        601 stride=1
                        602 pad=1
                    →  603 filters=18
                        604 activation=linear
                        605 
                        606 
                        607 [yolo]
                        608 mask = 6,7,8
                        609 anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
                    →  610 classes=1
                        611 num=9
                        612 jitter=.3
                        613 ignore_thresh = .7
                        614 truth_thresh = 1
                        615 random=1


                        685 [convolutional]
                        686 size=1
                        687 stride=1
                        688 pad=1
                    →  689 filters=18
                        690 activation=linear
                        691 
                        692 
                        693 [yolo]
                        694 mask = 3,4,5
                        695 anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
                    →  696 classes=1
                        697 num=9
                        698 jitter=.3
                        699 ignore_thresh = .7
                        700 truth_thresh = 1
                        701 random=1

                        772 [convolutional]
                        773 size=1
                        774 stride=1
                        775 pad=1
                    →  776 filters=18
                        777 activation=linear


                        780 [yolo]
                        781 mask = 0,1,2
                        782 anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
                    →  783 classes=1

                     

                    □darknetディレクトリの構成

                     

                    darknet/
                      ├ backup/
                      ├ cfg/
                      │  ├ yolov3.cfg
                      │  ├ obj.data
                      │  ├ obj.name
                     省略
                      ├ face/
                      │  ├ test.txt
                      │  ├ train.txt
                      │  ├0--Parade
                      │  ├2--Demonstration
                     省略
                      ├ darknet
                      ├ Makefile
                      ├ darknet53.conv.74
                     省略

                     

                    ■学習実行

                     

                    ./darknet detector train cfg/obj.data cfg/yolov3.cfg darknet53.conv.74

                     

                    エラーになる。


                    yolov3
                    layer     filters    size              input                output
                       0 conv     32  3 x 3 / 1   416 x 416 x   3   ->   416 x 416 x  32 0.299 BF
                       1 conv     64  3 x 3 / 2   416 x 416 x  32   ->   208 x 208 x  64 1.595 BF
                      省略
                      35 conv    256  3 x 3 / 1    52 x  52 x 128   ->    52 x  52 x 256 1.595 BF
                      36 Shortcut Layer: 33
                      37  Try to set subdivisions=64 in your cfg-file. 
                    CUDA status Error: file: ./src/cuda.c : () : line: 213 : build time: Mar  9 2019 - 09:54:27 
                    CUDA Error: out of memory
                    CUDA Error: out of memory: File exists
                    darknet: ./src/utils.c:281: error: Assertion `0' failed.
                    中止 (コアダンプ)

                     

                     

                    メモリが足りないってよ。
                    GT1030の搭載メモリは2Gバイト

                    ここで試行錯誤。
                          6 batch=24
                          7 subdivisions=8
                    の数字をいろいろイジっても駄目で。


                    google先生に聞いてみた。

                     

                    先人の声
                    「私はあなたのGPUのメモリが不足していると思います。 
                     Yolov3が完全にGPUにロードされたとき、
                     それは私のコンピュータ上でデフォルト設定(416 * 416)と
                     プラス表示および他のアプリケーションから
                     300ish MiBで約1600MBのメモリを必要とします。 
                     より大きなメモリを搭載したGPUで実行するか、
                     cfgファイルの幅と高さの設定を減らしてみてください
                     (サイズを小さくすると、検出結果に影響が出る可能性があります)。」
                     
                    と仰っております。
                    画面フレーム?のサイズを減らすと検出結果に影響が出るよ。
                    と言っておられますがGT1030しか持っていないのでしょうがないよねー
                    「ふん。働いてお金を沢山貯めてもっと良いのを買うんだ!!」
                    しかし画面フレーム?のサイズを減らせばGPUのメモリ消費が少ないとの事なので
                    半分ぐらいにして再度実行

                     →まだエラーになる。
                    では元の数字の4分の1ぐらいで実行。なんかうまく行くっぽい。

                     

                    追加の変更は以下の通り。

                     

                    vi cfg/yolov3.cfg


                    Line 8:width=128に設定
                    Line 9:height=128に設定

                          1 [net]
                          2 # Testing
                          3 # batch=1    ←コメントにした
                          4 # subdivisions=1 ←コメントにした
                          5 # Training
                          6 batch=24     ←コメントを外して24にした
                          7 subdivisions=8  ←コメントを外して8にした
                          8 width=128   ←128にした
                          9 height=128  ←128にした
                         10 channels=3
                         11 momentum=0.9

                     

                    後ろの方のfiltersとclassesはそのまま同じ


                    Line 603:filters=18に設定
                    Line 610:classes=1に設定
                    Line 689:filters=18に設定
                    Line 696:classes=1に設定
                    Line 776:filters=18に設定
                    Line 783:classes=1に設定

                     

                    □学習の様子

                     

                     136: 103.537476, 132.362717 avg loss, 0.000000 rate, 1.965623 seconds, 3264 images
                    Loaded: 0.000034 seconds
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.510125, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.442774, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.137911, Class: 0.430334, Obj: 0.358204, No Obj: 0.337541, .5R: 0.031250, .75R: 0.000000,  count: 32
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.511793, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.444947, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.050849, Class: 0.419898, Obj: 0.387084, No Obj: 0.337189, .5R: 0.000000, .75R: 0.000000,  count: 69
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.507179, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.442994, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.038144, Class: 0.419298, Obj: 0.349665, No Obj: 0.337408, .5R: 0.000000, .75R: 0.000000,  count: 64
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.508707, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.442302, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.320144, Class: 0.395719, Obj: 0.325046, No Obj: 0.337644, .5R: 0.250000, .75R: 0.250000,  count: 4
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.513188, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.444114, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.062433, Class: 0.457910, Obj: 0.391780, No Obj: 0.337275, .5R: 0.000000, .75R: 0.000000,  count: 44
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.507034, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.443162, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.150425, Class: 0.570029, Obj: 0.337372, No Obj: 0.337979, .5R: 0.000000, .75R: 0.000000,  count: 7
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.512920, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.443773, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.057833, Class: 0.500358, Obj: 0.431524, No Obj: 0.336149, .5R: 0.000000, .75R: 0.000000,  count: 57
                    Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.512746, .5R: -nan, .75R: -nan,  count: 0
                    Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.444053, .5R: -nan, .75R: -nan,  count: 0
                    Region 106 Avg IOU: 0.366167, Class: 0.522596, Obj: 0.302629, No Obj: 0.339804, .5R: 0.000000, .75R: 0.000000,  count: 7


                    nvidia-smi -l で見ていると


                    GPUの使用率はほぼ100%に張り付き
                    メモリーが1992Mしか搭載していないところ
                      1658Mバイト使用している。

                     

                    Sat Mar  9 16:33:12 2019       
                    +-----------------------------------------------------------------------------+
                    | NVIDIA-SMI 390.116                Driver Version: 390.116                   |
                    |-------------------------------+----------------------+----------------------+
                    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
                    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
                    |===============================+======================+======================|
                    |   0  GeForce GT 1030     Off  | 00000000:01:00.0  On |                  N/A |
                    | 57%   61C    P0    N/A /  30W |   1658MiB /  1992MiB |     97%      Default |
                    +-------------------------------+----------------------+----------------------+
                                                                                                   
                    +-----------------------------------------------------------------------------+
                    | Processes:                                                       GPU Memory |
                    |  GPU       PID   Type   Process name                             Usage      |
                    |=============================================================================|
                    |    0       861      G   /usr/lib/xorg/Xorg                           152MiB |
                    |    0      1005      G   /usr/bin/gnome-shell                         117MiB |
                    |    0      9839      G   ...uest-channel-token=11718656754115347387    27MiB |
                    |    0     17442      C   ./darknet                                   1349MiB |
                    +-----------------------------------------------------------------------------+


                    うまく行く予感しかしない。
                    ちなみにCPUの使用率はほぼぼ0でした。


                    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
                     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
                     0  0      0 241176 315680 10381696    0    0     0     0 1049 1705 21  5 74  0  0
                     0  0      0 241476 315680 10381696    0    0     0     0  396 1413  2  3 94  0  0
                     1  0      0 241352 315680 10381696    0    0     0     0  441 1783  3  3 94  0  0
                     1  0      0 241352 315680 10381696    0    0     0     0 1078 1552 22  2 75  0  0
                     0  0      0 241104 315680 10381696    0    0     0     0  449 1676  4  2 94  0  0
                     0  0      0 241228 315680 10381696    0    0     0     0 1043 1937 21  4 75  0  0


                    CPUも使ったほうが、もう少しは早いかもと思ったりとか、
                      実はGPU無しでも結構行けるのでは?
                    などと思うのは無謀なのだろうか?

                     

                    これで終わるまで待つ。
                    いやいや、参考ページによると「avg lossに変化が見られなくなったので強制終了」となっているので
                    時々avg lossの数字を確認する必要がありそうです。
                    最初が340ぐらい。

                    これで一晩放置プレー。おれは酒を飲む。そして寝る。zzzz..

                     

                    そして朝。

                    さて、avg lossの数字を確認する。
                    4.32とかになっております。

                    これで行けそうな気がするので

                     

                    darknet/backupフォルダーを確認すると
                    -rw-r--r-- 1 miha miha 246305388  3月  9 17:14 yolov3_1000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 17:57 yolov3_2000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 18:39 yolov3_3000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 19:22 yolov3_4000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 20:05 yolov3_5000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 20:46 yolov3_6000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 21:28 yolov3_7000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 22:10 yolov3_8000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 22:52 yolov3_9000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月  9 23:34 yolov3_10000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 00:17 yolov3_11000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 01:00 yolov3_12000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 01:41 yolov3_13000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 02:22 yolov3_14000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 03:03 yolov3_15000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 03:45 yolov3_16000.weights
                    -rw-r--r-- 1 miha miha 246305388  3月 10 04:05 yolov3_last.weights

                     

                    とファイルが出来ております。なんかすごく早起きしちゃいました。11時間経過ぐらいでしょうか?
                    ファイル名を見ると、40分おきぐらいに1000づつ数字が加算されていますね。
                    これは学習回数との事。

                     

                    これの最後のlastをいつものWindowsのchainer+yoloの環境に持っていって顔を認識できるか試す。

                     

                    ■chainer+yolo3で顔認識

                     

                    □chainerで読み込めるnpzの形式に変更する

                     

                    copy yolov3_last.weights yolo3-face_final.weights
                    python darknet2npz.py --model yolo_v3 --n-fg-class 1 yolo3-face_final.weights yolo3-face_final.weights.npz

                     

                    □classの一覧ファイルの作成

                     

                    yolo3-face.list
                    以下の内容で作成

                     

                    face

                     

                    □実行!!

                     

                    python yolo3.py --pretrained-model yolo3-face_final.weights.npz --class_num 1 --class_list yolo3-face.list 0

                     

                    最後のパラメーター0はビデオストリーミングの0からリアルタイム

                    その代わりにファイル名を指定すればファイルに対して処理を行う。

                     

                    □実行結果

                     

                    python yolo3.py --pretrained-model yolo3-face_final.weights.npz --class_num 1 --class_list yolo3-face.list face.jpg

                     

                     

                    python yolo3.py --pretrained-model yolo3-face_final.weights.npz --class_num 1 --class_list yolo3-face.list face2.jpg

                     

                     

                    □プログラムは前と同じ

                     

                    import time
                    import argparse
                    import matplotlib.pyplot as plt
                    import cv2
                    import numpy as np
                    from timeit import default_timer as timer
                    import chainer
                    from chainercv.datasets import voc_bbox_label_names
                    from chainercv.datasets import coco_bbox_label_names
                    from chainercv.links import YOLOv3

                    #色のテーブル 150まで対応
                    label_colors = (
                        (120, 120, 120),
                        (180, 120, 120),
                        (6, 230, 230),
                        (80, 50, 50),
                        (4, 200, 3),
                        (120, 120, 80),
                        (140, 140, 140),
                        (204, 5, 255),
                        (230, 230, 230),
                        (4, 250, 7),
                        (224, 5, 255),
                        (235, 255, 7),
                        (150, 5, 61),
                        (120, 120, 70),
                        (8, 255, 51),
                        (255, 6, 82),
                        (143, 255, 140),
                        (204, 255, 4),
                        (255, 51, 7),
                        (204, 70, 3),
                        (0, 102, 200),
                        (61, 230, 250),
                        (255, 6, 51),
                        (11, 102, 255),
                        (255, 7, 71),
                        (255, 9, 224),
                        (9, 7, 230),
                        (220, 220, 220),
                        (255, 9, 92),
                        (112, 9, 255),
                        (8, 255, 214),
                        (7, 255, 224),
                        (255, 184, 6),
                        (10, 255, 71),
                        (255, 41, 10),
                        (7, 255, 255),
                        (224, 255, 8),
                        (102, 8, 255),
                        (255, 61, 6),
                        (255, 194, 7),
                        (255, 122, 8),
                        (0, 255, 20),
                        (255, 8, 41),
                        (255, 5, 153),
                        (6, 51, 255),
                        (235, 12, 255),
                        (160, 150, 20),
                        (0, 163, 255),
                        (140, 140, 140),
                        (250, 10, 15),
                        (20, 255, 0),
                        (31, 255, 0),
                        (255, 31, 0),
                        (255, 224, 0),
                        (153, 255, 0),
                        (0, 0, 255),
                        (255, 71, 0),
                        (0, 235, 255),
                        (0, 173, 255),
                        (31, 0, 255),
                        (11, 200, 200),
                        (255, 82, 0),
                        (0, 255, 245),
                        (0, 61, 255),
                        (0, 255, 112),
                        (0, 255, 133),
                        (255, 0, 0),
                        (255, 163, 0),
                        (255, 102, 0),
                        (194, 255, 0),
                        (0, 143, 255),
                        (51, 255, 0),
                        (0, 82, 255),
                        (0, 255, 41),
                        (0, 255, 173),
                        (10, 0, 255),
                        (173, 255, 0),
                        (0, 255, 153),
                        (255, 92, 0),
                        (255, 0, 255),
                        (255, 0, 245),
                        (255, 0, 102),
                        (255, 173, 0),
                        (255, 0, 20),
                        (255, 184, 184),
                        (0, 31, 255),
                        (0, 255, 61),
                        (0, 71, 255),
                        (255, 0, 204),
                        (0, 255, 194),
                        (0, 255, 82),
                        (0, 10, 255),
                        (0, 112, 255),
                        (51, 0, 255),
                        (0, 194, 255),
                        (0, 122, 255),
                        (0, 255, 163),
                        (255, 153, 0),
                        (0, 255, 10),
                        (255, 112, 0),
                        (143, 255, 0),
                        (82, 0, 255),
                        (163, 255, 0),
                        (255, 235, 0),
                        (8, 184, 170),
                        (133, 0, 255),
                        (0, 255, 92),
                        (184, 0, 255),
                        (255, 0, 31),
                        (0, 184, 255),
                        (0, 214, 255),
                        (255, 0, 112),
                        (92, 255, 0),
                        (0, 224, 255),
                        (112, 224, 255),
                        (70, 184, 160),
                        (163, 0, 255),
                        (153, 0, 255),
                        (71, 255, 0),
                        (255, 0, 163),
                        (255, 204, 0),
                        (255, 0, 143),
                        (0, 255, 235),
                        (133, 255, 0),
                        (255, 0, 235),
                        (245, 0, 255),
                        (255, 0, 122),
                        (255, 245, 0),
                        (10, 190, 212),
                        (214, 255, 0),
                        (0, 204, 255),
                        (20, 0, 255),
                        (255, 255, 0),
                        (0, 153, 255),
                        (0, 41, 255),
                        (0, 255, 204),
                        (41, 0, 255),
                        (41, 255, 0),
                        (173, 0, 255),
                        (0, 245, 255),
                        (71, 0, 255),
                        (122, 0, 255),
                        (0, 255, 184),
                        (0, 92, 255),
                        (184, 255, 0),
                        (0, 133, 255),
                        (255, 214, 0),
                        (25, 194, 194),
                        (102, 255, 0),
                        (92, 0, 255),
                        (0, 0, 0)
                    )

                    def main():
                        parser = argparse.ArgumentParser()
                        parser.add_argument('--gpu', type=int, default=-1)
                        parser.add_argument('--pretrained-model', default='voc0712')
                        parser.add_argument('--class_num', default=20)
                        parser.add_argument('--class_list', default=0)
                        parser.add_argument('video')
                        args = parser.parse_args()

                        #
                        #パラメータ解析
                        # python yolo3.py 0
                        #    デフォルトではvoc0712のモデルをダウンロードして来ます。認識できるのは20種類
                        #
                        # python yolo3.py --pretrained-model yolov3.weights.npz --class_num 80 --class_list yolov3.list 0
                        #  --pretrained-model 
                        #    darknet2npz.pyで変換した学習済みモデルyolov3.weights.npzを指定
                        #  --class_num
                        #    上記学習済みモデルのクラス数
                        #  --class_list
                        #    上記学習済みモデルのクラス名一覧 1行に1クラス
                        #  ビデオ
                        #    WEBカメラの場合は0
                        #    動画ファイルの場合はファイル名
                        #
                        if args.pretrained_model=='voc0712' :
                          label_names = voc_bbox_label_names
                          model = YOLOv3(20, 'voc0712')
                        else :
                          print(args.class_list)
                          if args.class_list==0 : 
                            label_names = coco_bbox_label_names
                          else:
                            f = open(args.class_list, "r")
                            name_list = []
                            for line in f:
                              line = line.strip()
                              name_list.append(line)
                            f.close()
                            label_names = name_list
                          
                          model = YOLOv3(n_fg_class=int(args.class_num), pretrained_model=args.pretrained_model)
                        
                        #GPU対応
                        #  CPUなら省略
                        #  GPUなら0
                        if args.gpu >= 0:
                            chainer.cuda.get_device_from_id(args.gpu).use()
                            model.to_gpu()
                        #
                        #対応しているクラス名一覧を表示する
                        #
                        for name in label_names:
                          print(name)
                        #
                        #WEBカメラまたは動画ファイルを開く
                        #
                        if args.video == "0":
                            vid = cv2.VideoCapture(0)
                        else:
                            vid = cv2.VideoCapture(args.video)
                        if not vid.isOpened():
                            raise ImportError("Couldn't open video file or webcam.")

                        
                        # Compute aspect ratio of video
                        vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                        vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                        # vidar = vidw / vidh
                        print(vidw)
                        print(vidh)

                        accum_time = 0
                        curr_fps = 0
                        fps = "FPS: ??"
                        prev_time = timer()

                        frame_count = 1
                        while True:
                            ret, frame = vid.read()
                            if ret == False:
                                time.sleep(5)
                                print("Done!")
                                return

                            # BGR -> RGB
                            rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                            # Result image
                            result = frame.copy()

                            # (H, W, C) -> (C, H, W)
                            img = np.asarray(rgb, dtype = np.float32).transpose((2, 0, 1))

                            # Object Detection
                            bboxes, labels, scores = model.predict([img])
                            bbox, label, score = bboxes[0], labels[0], scores[0]

                            print("----------")
                            nPerson = 0
                            nBottle = 0
                            if len(bbox) != 0:
                                for i, bb in enumerate(bbox):
                                    # print(i)
                                    lb = label[i]
                                    conf = score[i].tolist()
                                    ymin = int(bb[0])
                                    xmin = int(bb[1])
                                    ymax = int(bb[2])
                                    xmax = int(bb[3])

                                    class_num = int(lb)

                                    # Draw box 1
                                    cv2.rectangle(result, (xmin, ymin), (xmax, ymax),
                                    label_colors[class_num], 2)

                                    # Draw box 2
                                    # cv2.rectangle(result, (xmin, ymin), (xmax, ymax), (0,255,0), 2)

                                    #text = label_names[class_num] + " " + ('%.2f' % conf)
                                    text = label_names[class_num] + " " + ('%.2f' % conf)
                                    print(text)
                                    if(label_names[class_num] == 'person'):
                                      nPerson = nPerson + 1
                                    if(label_names[class_num] == 'bottle'):
                                      nBottle = nBottle + 1
                                    
                                    text_top = (xmin, ymin - 10)
                                    text_bot = (xmin + 80, ymin + 5)
                                    text_pos = (xmin + 5, ymin)

                                    # Draw label 1
                                    cv2.rectangle(result, text_top, text_bot, 
                                    label_colors[class_num], -1)
                                    cv2.putText(result, text, text_pos, 
                                    cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)

                                    # Draw label 2
                                    # cv2.rectangle(result, text_top, text_bot, (255,255,255), -1)
                                    # cv2.putText(result, text, text_pos, 
                                    # cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)
                                print("==========")
                                print("Number of people : " + str(nPerson))
                                print("Number of bottle : " + str(nBottle))
                            # Calculate FPS
                            curr_time = timer()
                            exec_time = curr_time - prev_time
                            prev_time = curr_time
                            accum_time = accum_time + exec_time
                            curr_fps = curr_fps + 1
                            if accum_time > 1:
                                accum_time = accum_time - 1
                                fps = "FPS:" + str(curr_fps)
                                curr_fps = 0


                     


                    darknetとかyoloで顔認識したい。失敗

                    2
                    • miha
                      2019-03-10 08:55:21

                    • miha
                      2019-03-10 08:55:21

                    darknetとかyoloで顔認識したい。失敗

                     

                    ■顔学習環境の作成

                     

                     core i5 のメモリ16GB搭載のマシンが余っていたので
                     これに Geforce GT 1030 を入れて
                     学習環境を作成する

                     https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed
                     これのページどおりに実施すればOK

                     

                    □OSインストール

                     

                     https://www.ubuntu.com/download/desktop
                     から
                     Ubuntu 18.04TLSをダウンロード。
                     DVDに焼いて普通にインストール。全部デフォルトでOK

                     

                    □いろいろインストール

                     

                    sudo apt-get update
                    sudo apt-get upgrade

                    最新になるまで何度か行う。

                     

                    sudo apt-get install -y vim csh flex gfortran libgfortran3 g++ ¥
                                     cmake xorg-dev patch zlib1g-dev libbz2-dev ¥
                                     libboost-all-dev openssh-server libcairo2 ¥
                                     libcairo2-dev libeigen3-dev lsb-core ¥
                                     lsb-base net-tools network-manager ¥
                                     git-core git-gui git-doc xclip gdebi-core libffi-dev ¥
                                     make build-essential libssl-dev zlib1g-dev libbz2-dev ¥
                                     libreadline-dev libsqlite3-dev wget curl llvm ¥
                                     libncurses5-dev libncursesw5-dev ¥
                                     xz-utils tk-dev libffi-dev liblzma-dev python-openssl


                    □G++-7とBoostLibが動作しているか確認

                     

                    ・以下のファイルを作成
                    test_boost.cpp

                     

                    #include <boost/lambda/lambda.hpp>
                    #include <iostream>
                    #include <iterator>
                    #include <algorithm>

                    int main()
                    {
                        using namespace boost::lambda;
                        typedef std::istream_iterator<int> in;

                        std::for_each(
                            in(std::cin), in(), std::cout << (_1 * 3) << " " );
                    }

                     

                    ・コンパイルして実行
                    g++-7 test_boost.cpp -o test_boost
                    echo 3 6 9 | ./test_boost

                    9 18 27と出力されればOK

                     

                    □nvidia-driver のインストール

                     

                    https://www.nvidia.com/Download/index.aspx

                     

                    グラボに合っているドライバーを確認
                    (ダウンロードするわけではない)

                     

                    sudo apt-get purge nvidia-*
                    sudo add-apt-repository ppa:graphics-drivers/ppa
                    sudo apt-get update

                    sudo apt-get install nvidia-driver-415
                    ※nvidia-driver-415の部分をあなたのグラボと合わせる

                     

                    □再起動

                     

                    reboot
                    再起動を待つ

                     

                    □GPUの状況を確認
                     
                    nvidia-smi

                     

                    こんな感じで出るっす。

                     

                    miha@linux:~/test_boost$ nvidia-smi 
                    Sun Mar  3 09:58:14 2019       
                    +-----------------------------------------------------------------------------+
                    | NVIDIA-SMI 415.27       Driver Version: 415.27       CUDA Version: 10.0     |
                    |-------------------------------+----------------------+----------------------+
                    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
                    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
                    |===============================+======================+======================|
                    |   0  GeForce GT 1030     Off  | 00000000:01:00.0 Off |                  N/A |
                    | 38%   35C    P0    N/A /  30W |    420MiB /  2000MiB |      0%      Default |
                    +-------------------------------+----------------------+----------------------+
                                                                                                   
                    +-----------------------------------------------------------------------------+
                    | Processes:                                                       GPU Memory |
                    |  GPU       PID   Type   Process name                             Usage      |
                    |=============================================================================|
                    |    0       892      G   /usr/lib/xorg/Xorg                           182MiB |
                    |    0      1111      G   /usr/bin/gnome-shell                         157MiB |
                    |    0      1540      G   ...uest-channel-token=15854222783359571361    78MiB |
                    +-----------------------------------------------------------------------------+

                     

                    miha@linux:~/test_boost$ 

                    GPU使っていればVolatile GPU-Utilの所の数字が上がるっす。
                    ちなみに、自分の環境ではGT1030が1枚ですが複数のGPU搭載の場合はここに何行か出てきます。

                     

                    □CUDAのインストール

                     

                    参考にしたページ
                    https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed
                    に色々書いてあるが、
                    CUDA10.0はTensorFlowで動かないとか
                    2018/11/30時点でのTensorFlow 1.12.0での Software requirementsに従って
                    CUDAは9を採用する。

                    これ駄目。sudo apt-get install cudaをするとnvidia-driverが削除されるとの事。

                    sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub

                    wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.1.85-1_amd64.deb

                    sudo apt install ./cuda-repo-ubuntu1604_9.1.85-1_amd64.deb

                    wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

                    sudo apt install ./nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

                    sudo apt update

                    sudo apt install cuda9.0 cuda-cublas-9-0 cuda-cufft-9-0 cuda-curand-9-0 ¥
                        cuda-cusolver-9-0 cuda-cusparse-9-0 libcudnn7=7.2.1.38-1+cuda9.0 ¥
                        libnccl2=2.2.13-1+cuda9.0 cuda-command-line-tools-9-0

                     

                    □cuDNNのインストール

                     

                    https://developer.nvidia.com/rdp/form/cudnn-download-survey
                    にサインアップして

                    cuDNN Library for Linuxをダウンロード

                    cudnn-9.2-linux-x64-v7.5.0.56.tgz

                     

                    □libcuptiをインストール

                     

                    sudo apt-get install libcupti-dev

                     

                    □ファイルを展開して所定の位置にコピー

                     

                    tar -zxvf cudnn-9.2-linux-x64-v7.5.0.56.tgz
                    sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda-9.0/lib64/
                    sudo cp cuda/include/cudnn.h /usr/local/cuda-9.0/include/
                    sudo chmod a+r /usr/local/cuda-9.0/include/cudnn.h /usr/local/cuda/lib64/libcudnn*

                     

                    □pyenvを入れてpython環境を切り替えできるようにする

                     

                    git clone https://github.com/yyuu/pyenv.git ~/.pyenv

                     

                    ・パスを通す

                     

                    vi ~/.bashrc

                    以下の行を追加
                    export PYENV_ROOT="$HOME/.pyenv"
                    export PATH="$PYENV_ROOT/bin:$PATH"
                    eval "$(pyenv init -)"

                     

                    □python3.6.8をインストール

                     

                    pyenv install 3.6.8
                    pyenv global 3.6.8
                    pyenv rehash
                    python -V

                     

                    □venvで仮想環境を作成する

                     

                    cd
                    mkdir workspace
                    cd workspace
                    sudo apt-get install python3-venv
                    python3 -m venv TensorFlow
                    source TensorFlow/bin/activate

                     

                    □tensorflowをインストールする

                     

                    pip install tensorflow-gpu==1.12.0

                     

                    □minstが動作するか確認する

                     

                    vi test_mnist.py

                     

                    以下の内容で作成

                     

                    import tensorflow as tf
                    mnist = tf.keras.datasets.mnist

                    (x_train, y_train),(x_test, y_test) = mnist.load_data()
                    x_train, x_test = x_train / 255.0, x_test / 255.0

                    model = tf.keras.models.Sequential([
                      tf.keras.layers.Flatten(),
                      tf.keras.layers.Dense(512, activation=tf.nn.relu),
                      tf.keras.layers.Dropout(0.2),
                      tf.keras.layers.Dense(10, activation=tf.nn.softmax)
                    ])
                    model.compile(optimizer='adam',
                                  loss='sparse_categorical_crossentropy',
                                  metrics=['accuracy'])

                    model.fit(x_train, y_train, epochs=5)
                    model.evaluate(x_test, y_test)

                     

                    ・実行

                     

                    python test_mnist.py

                     

                    ・こんな感じで実行される

                     

                    (TensorFlow) miha@linux:~/workspace$ python test_mnist.py
                    Epoch 1/5
                    2019-03-03 10:21:47.707416: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
                    2019-03-03 10:21:47.793110: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:964] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
                    2019-03-03 10:21:47.793568: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties: 
                    name: GeForce GT 1030 major: 6 minor: 1 memoryClockRate(GHz): 1.468
                    pciBusID: 0000:01:00.0
                    totalMemory: 1.95GiB freeMemory: 1.48GiB
                    2019-03-03 10:21:47.793587: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
                    2019-03-03 10:21:48.036911: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
                    2019-03-03 10:21:48.036946: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988]      0 
                    2019-03-03 10:21:48.036953: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0:   N 
                    2019-03-03 10:21:48.037173: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1230 MB memory) -> physical GPU (device: 0, name: GeForce GT 1030, pci bus id: 0000:01:00.0, compute capability: 6.1)
                       32/60000 [..............................] - ETA: 20:08 - loss: 2.4107 - acc:   544/60000 [..............................] - ETA: 1:16 - loss: 1.5640 - acc: 0 1056/60000 [..............................] - ETA: 41s - loss: 1.1520 - acc: 0. 1568/60000 [..............................] - ETA: 29s - loss: 0.9480 - acc: 0. 2080/60000 [>.............................] - ETA: 23s - loss: 0.8366 - acc: 0. 2592/60000 [>.............................] - ETA: 20s - loss: 0.7556 - acc: 0. 3104/60000 [>.............................] - ETA: 17s - loss: 0.6932 - acc: 0. 3616/60000 [>.............................] - ETA: 15s - loss: 0.6532 - acc: 0. 4096/60000 [=>............................] - ETA: 14s - loss: 0.6160 - acc: 0. 4544/60000 [=>............................] - ETA: 13s - loss: 0.5943 - acc: 0. 5024/60000 [=>............................] - ETA: 12s - loss: 0.5691 - acc: 0. 5536/60000 [=>............................] - ETA: 11s - loss: 0.5550 - acc: 0. 6016/60000 [==>...........................] - ETA: 11s - loss: 0.5339 - acc: 0. 6560/60000 [==>...........................] - ETA: 10s - loss: 0.5168 - acc: 0. 7072/60000 [==>...........................] - ETA: 10s - loss: 0.5001 - acc: 0. 7552/60000 [==>...........................] - ETA: 9s - loss: 0.4895 - acc: 0.8 8032/60000 [===>..........................] - ETA: 9s - loss: 0.4772 - acc: 0.8 8544/60000 [===>..........................] - ETA: 9s - loss: 0.4635 - acc: 0.8 9024/60000 [===>..........................] - ETA: 8s - loss: 0.4544 - acc: 0.8 9504/60000 [===>..........................] - ETA: 8s - loss: 0.4432 - acc: 0.810048/60000 [====>.........................] - ETA: 8s - loss: 0.4348 - acc: 0.810528/60000 [====>.........................] - ETA: 8s - loss: 0.4251 - acc: 0.811040/60000 [====>.........................] - ETA: 7s - loss: 0.4166 - acc: 0.811552/60000 [====>.........................] - ETA: 7s - loss: 0.4097 - acc: 0.8


                    ・GPUの使用状況を確認

                     

                    実行中に以下のコマンドで

                     

                    nvidia-smi -l

                     

                    GPUの使用状況を確認

                    Volatile GPU-Utilが73%になっているのでOK

                    +-----------------------------------------------------------------------------+
                    | NVIDIA-SMI 415.27       Driver Version: 415.27       CUDA Version: 10.0     |
                    |-------------------------------+----------------------+----------------------+
                    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
                    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
                    |===============================+======================+======================|
                    |   0  GeForce GT 1030     Off  | 00000000:01:00.0 Off |                  N/A |
                    | 38%   37C    P0    N/A /  30W |   1811MiB /  2000MiB |     73%      Default |
                    +-------------------------------+----------------------+----------------------+
                                                                                                   
                    +-----------------------------------------------------------------------------+
                    | Processes:                                                       GPU Memory |
                    |  GPU       PID   Type   Process name                             Usage      |
                    |=============================================================================|
                    |    0       892      G   /usr/lib/xorg/Xorg                           182MiB |
                    |    0      1111      G   /usr/bin/gnome-shell                         180MiB |
                    |    0      1540      G   ...uest-channel-token=15854222783359571361    76MiB |
                    |    0     21830      C   python                                      1361MiB |
                    +-----------------------------------------------------------------------------+


                    ここまででGPUが使用できる環境が整った

                     

                    ■顔の学習の元になる顔の写真と顔の座標のファイルを整備

                     

                    学習させるには顔の写真と、その写真の中の何処が顔なのかを入力する必要があり。
                    その元になるファイルは色んなサイトで公開してもらっているようなので
                    これを使用する。

                    参考にしたページ
                    https://qiita.com/ha9kberry/items/1bc113cfcd9892a9ddbd
                    いつも助かっています。

                     

                    □顔の学習のもとになる顔の写真と顔の座標のファイルをダウンロード

                     

                    http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/

                    WIDER Face Training Images

                    Face annotations
                    をダウンロードして解凍する

                    こんな感じで
                    .
                    ├── WIDER_train展開されます
                    │   └── images
                    │       ├── 0--Parade
                    │       │   ├── 0_Parade_Parade_0_1014.jpg
                    │       │   ├── 0_Parade_Parade_0_1019.jpg
                    │       │   ├── 0_Parade_Parade_0_1040.jpg
                    │       │   ├── 0_Parade_Parade_0_1041.jpg
                      省略
                    │       ├── 1--Handshaking
                    │       │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │       │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │       │   ├── 1_Handshaking_Handshaking_1_113.jpg
                     省略
                    │           ├── 9_Press_Conference_Press_Conference_9_944.jpg
                    │           ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │           └── 9_Press_Conference_Press_Conference_9_97.jpg
                    ├── wider_face_split
                        ├── readme.txt
                        ├── wider_face_test.mat
                        ├── wider_face_test_filelist.txt
                        ├── wider_face_train.mat
                        ├── wider_face_train_bbx_gt.txt
                        ├── wider_face_val.mat
                        └── wider_face_val_bbx_gt.txt

                    で、中を見ると集合写真とかのjpgが沢山と
                     wider_face_train_bbx_gt.txtが顔の座標が入っている模様。

                     

                    □Annotationファイル作成

                     

                    参考ページを参考にして。
                    参考ページの人はJupyter Notebookを使用しているようなんですが
                    自分は違うので自分で環境整備します。

                     

                    pip install opencv-python

                     

                    で、ファイルを作成

                     

                    vi generator.py

                     

                    import os
                    import cv2
                    import math
                    import random

                    txt_file = 'wider_face_split/wider_face_train_bbx_gt.txt'
                    with open(txt_file) as f:
                        num = f.read().count('jpg')
                    print('number of images:',num)

                     

                    そのまま実行すると
                    number of images: 12880
                    となるんです。

                    参考ページによるとなんでかはわかりませんけど
                    「予め0--Parade〜20--Family_Groupのみ抽出」となっていますんで

                    wider_face_train_bbx_gt.txtを開いて
                    0--Parade〜20--Family_Groupだけ残す。

                    ちなみに、このファイルの番号が曲者で
                    普通に20--Family_Groupの後ろを削除すればOKと思うじゃないですが。
                    しかーし、よく見ると
                    20--Family_Groupのあとには21--Festival/21_Festival_Festival_21_14.jpgが有って
                    その後ろは22→23→・・・・と続きますが
                    29の次が3--Riot/3_Riot_Riot_3_189.jpgになるので注意です。

                    それと、もう一つ。
                    Ubuntuに最初から入っていたテキストエディターなんですが、
                    これでやると、セーブしたときにファイルが崩れます。
                    適当に他の行とくっついて以下のような行が発生して後ろの工程でエラーになりますので注意です。
                    「264--Dancing/4_Dancing_Dancing_4_71.jpg」

                    もう一回実行

                    (TensorFlow) miha@linux:~/workspace/test$ python generator.py 
                    number of images: 5451
                    (TensorFlow) miha@linux:~/workspace/test$ 

                    参考ページと同じでok


                    □Annotationファイル構成

                     

                    0_Parade_marchingband_1_45.txt
                    0 0.68017578125 0.9162995594713657 0.0400390625 0.07342143906020558
                    0 0.02978515625 0.8127753303964758 0.0185546875 0.027900146842878122

                    - 各バウンディングボックスごとにクラス x座標 y座標 ボックス幅 ボックス高さ
                    - 座標はバウンディングボックスの中心座標
                    - 座標、幅・高さともに、画像の幅・高さに対する相対値
                    - Annotationファイルは、画像ファイルと同じディレクトリ内に保存

                     

                    generator2.py

                     

                    以下の内容で作成

                     

                    import cv2

                    def generator():
                        num = 4152
                        with open("wider_face_train_bbx_gt.txt") as f:
                            img_paths=[]

                            for i in range(num):
                                # 両端の空白や改行を除去して1行ずつ読み込む
                                img_path=f.readline().strip()
                                # 画像パス一覧取得
                                img_paths.append(img_path)
                                # 画像を読み込み幅・高さ取得
                                im = cv2.imread(img_path)
                                im_h, im_w, im_c = im.shape
                                # '/'で分割
                                split=img_path.split('/')
                                # Annotationファイルを格納するディレクトリ取得
                                dir_name=split[0]
                                # Annotationファイル名作成
                                file_name=split[1].replace('.jpg', '.txt')
                                # ボックス数取得
                                count = int(f.readline())
                                readline=[]
                                readlines=[]

                                for j in range(count):
                                    readline=f.readline().split()
                                    # ボックスの左上座標を取得
                                    xmin=int(readline[0])
                                    ymin=int(readline[1])
                                    # ボックスの幅・高さを取得
                                    w=int(readline[2])
                                    h=int(readline[3])
                                    # ボックスの中央座標(相対値)を作成
                                    xcenter=str((xmin+w/2)/im_w)
                                    ycenter=str((ymin+h/2)/im_h)
                                    # ボックスの幅・高さを相対値に変換
                                    w=str(w/im_w)
                                    h=str(h/im_h)

                                    class_num='0'
                                    # クラス x座標 y座標 ボックス幅 ボックス高さを半角スペースで結合
                                    string=' '.join([class_num, xcenter, ycenter, w, h])
                                    readlines.append(string)
                                # 改行で結合    
                                readlines_str='¥n'.join(readlines)
                                # 該当するディレクトリ内にAnnotationファイルを保存
                                with open(dir_name+'/'+file_name, 'w') as j:
                                    j.write(readlines_str)

                        # 画像パス一覧を出力
                        return img_paths

                    img_paths = generator()

                     

                    これを動かすのにディレクトリ構成を以下のように変更

                    .
                    ├── 0--Parade
                    │   ├── 0_Parade_Parade_0_1014.jpg
                    │   ├── 0_Parade_Parade_0_1019.jpg
                    │   ├── 0_Parade_Parade_0_1040.jpg
                     省略
                    ├── 1--Handshaking
                    │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   ├── 1_Handshaking_Handshaking_1_113.jpg
                     省略
                    │   ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │   └── 9_Press_Conference_Press_Conference_9_97.jpg
                    ├── generator2.py
                    └── wider_face_train_bbx_gt.txt

                     

                    generator2.pyとwider_face_train_bbx_gt.txtをimagesの中に移動して

                    そこで
                    python generator2.py を実行。

                    結果はjpgファイルのjpg部分をtxtにしたファイルが作成される
                    .
                    ├── 0--Parade
                    │   ├── 0_Parade_Parade_0_1014.jpg
                    │   ├── 0_Parade_Parade_0_1014.txt
                    │   ├── 0_Parade_Parade_0_1019.jpg
                    │   ├── 0_Parade_Parade_0_1019.txt
                    │   ├── 0_Parade_Parade_0_1040.jpg
                    │   ├── 0_Parade_Parade_0_1040.txt
                     省略
                    ├── 1--Handshaking
                    │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   ├── 1_Handshaking_Handshaking_1_102.txt
                    │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   ├── 1_Handshaking_Handshaking_1_105.txt
                    │   ├── 1_Handshaking_Handshaking_1_113.jpg
                    │   ├── 1_Handshaking_Handshaking_1_113.txt
                     省略
                    │   ├── 9_Press_Conference_Press_Conference_9_946.jpg
                    │   ├── 9_Press_Conference_Press_Conference_9_946.txt
                    │   ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │   └── 9_Press_Conference_Press_Conference_9_97.txt
                    ├── generator2.py
                    └── wider_face_train_bbx_gt.txt

                     

                    □trainデータ、testデータそれぞれで使う画像のパス一覧テキストファイルを作成

                    プログラムを見るとfaceというディレクトリの中のファイル一覧を取ってくるようになっているようなのと、0--Parade〜20--Family_Group以外が有るとうまく行かないようなんで
                    以下の構成に変更

                     

                    .
                    ├── face
                    │   ├── 0--Parade
                    │   │   ├── 0_Parade_Parade_0_1014.jpg
                    │   │   ├── 0_Parade_Parade_0_1014.txt
                    │   │   ├── 0_Parade_Parade_0_1019.jpg
                    │   │   ├── 0_Parade_Parade_0_1019.txt
                     省略
                    │   ├── 1--Handshaking
                    │   │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_102.txt
                    │   │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_105.txt
                     省略
                    │       ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │       └── 9_Press_Conference_Press_Conference_9_97.txt
                    ├── generator3.py
                    └── wider_face_split
                        └── wider_face_train_bbx_gt.txt

                     

                    ・実行
                     python generator3.py

                     

                    以下のファイルができる

                     

                    test.txt

                    face/18--Concerts/18_Concerts_Concerts_18_505.jpg
                    face/18--Concerts/18_Concerts_Concerts_18_973.jpg
                    face/18--Concerts/18_Concerts_Concerts_18_1008.jpg
                    face/18--Concerts/18_Concerts_Concerts_18_833.jpg
                    省略

                    test.txt
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_550.jpg
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_554.jpg
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_10.jpg
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_873.jpg
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_639.jpg
                    face/9--Press_Conference/9_Press_Conference_Press_Conference_9_226.jpg

                    ・結果的に以下のディレクトリ構成になる
                    .
                    ├── face
                    │   ├── 0--Parade
                    │   │   ├── 0_Parade_Parade_0_1014.jpg
                    │   │   ├── 0_Parade_Parade_0_1014.txt
                    │   │   ├── 0_Parade_Parade_0_1019.jpg
                    │   │   ├── 0_Parade_Parade_0_1019.txt
                     省略
                    │   ├── 1--Handshaking
                    │   │   ├── 1_Handshaking_Handshaking_1_102.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_102.txt
                    │   │   ├── 1_Handshaking_Handshaking_1_105.jpg
                    │   │   ├── 1_Handshaking_Handshaking_1_105.txt
                     省略
                    │       ├── 9_Press_Conference_Press_Conference_9_97.jpg
                    │       └── 9_Press_Conference_Press_Conference_9_97.txt
                    ├── generator3.py
                    ├── test.txt
                    ├── train.txt
                    └── wider_face_split
                        └── wider_face_train_bbx_gt.txt


                    ■DARKNETで学習させる

                     

                    □DARKNERをインストール

                     

                    git clone https://github.com/AlexeyAB/darknet.git

                    cd darknet

                    vi Makefile
                    以下の箇所を修正
                     GPU=1
                     CUDNN=1

                    make

                     

                    □トラブル発生。

                     

                    よくわからんがね。

                    makeでエラーって出るのさー。

                    cuda_runtime.hが無いと言われ。
                    findで探したパスを-Iに追加すると

                     

                    今度は
                    curand.hが無いと言われ。
                    findでcurand.hを探しても見つからないのさー

                    ちょっと、わからないので
                    アプローチの方法を変更して
                    また今度だね。

                     

                     


                    インバーターを作ってみる

                    0

                      インバーターを作ってみる

                       

                      JUGEMテーマ:電子工作

                       

                      youtubeの技術解説記事とか好きで時々見るんですが
                      https://www.youtube.com/watch?v=Scrik1grDK4

                       

                      インバーターを解説しておりまして、目から鱗の部分が沢山有りましたんで、手持ちの部品で出来るか実験実験。

                       

                      ■インバーターとは?


                       wikiによりますと 
                       「インバータとは、直流から、周波数の異なる交流を発生させる装置のこと」
                        ※判りにくいので意訳しております。
                       となっており、
                       電池とかの直流を交流100V、50Hzとかに変換する
                       停電の時にあると役に立つやつです。

                       

                      ■目標


                       手持ち部品にMOSFETの数が足りないのと、トランスが無いので
                       トランジスタで構成することにして
                       5V、50Hzの方形波を生成
                       最終的には5V、50Hzの正弦波を生成を目標にします。

                       

                      ■基本回路
                       
                       
                       
                       
                      ■基本回路の結果
                       AとBの電圧を測定すると
                       スイッチを右に倒した場合
                        -157.7mV
                       スイッチを左に倒した場合
                        +154.0mV
                       となるので、スイッチをパチパチパチパチ切り替えれば
                        -157.7mVと+154.0mVの方形派になるはず。
                       5V取り出せると良いんですが、さすがにトランジスターではむりっぽ。
                       
                      ■Arduinoを接続してみる

                       

                       このスイッチ部分をArduinoで制御してみたい。

                       

                      ■基本回路2

                       


                      ■基本回路2の結果

                       オシロに通すと以下の波形になる
                       
                       
                       
                       50Hzの方形波が出ているのでOK
                       
                      ■arduinoのプログラム


                      void setup() {
                        pinMode(2, OUTPUT);

                      }

                      void loop() {
                        digitalWrite(2, HIGH);
                        delay(10);
                        digitalWrite(2, LOW);
                        delay(10);
                      }

                       

                      ■これを正弦波にしてみる
                       
                       ここから先が難しそう。
                       きっかけになったyoutubeによると、
                       PWM的にデューティー比によりパルスを制御しつつ、それをLCRの回路で平均化して
                       正弦波とするって事らしい。
                       
                      ■基本回路3

                       


                      正弦波にするためにトランジスターの前にコンデンサーを挟んでみました。

                      で、ArduinoのD2はプラスマイナス切り替え用。
                        D3をデューティー比の切り替え用としてみた。

                       

                      ■基本回路3実行結果

                       オシロに通すと以下の波形になる

                       


                       
                       まあまあかな。プログラムをきちんとすればもう少しましになるんだろうけど、
                       今日はここまで。
                       次はFETでやってみますね。

                       

                      ■arduinoのプログラム

                       

                      void setup() {
                        Serial.begin(9600);
                        Serial.println("ver1.0");
                        Serial.println("start:");

                        pinMode(2, OUTPUT);
                        pinMode(3, OUTPUT);

                      }

                      int n=1;
                      int plus_minas = 1;
                      void loop() {

                        int bai = 50;

                      // 0V
                        digitalWrite(2, LOW);
                        digitalWrite(3, LOW);

                        for(int i=0;i<10;i++){
                      // +V
                          digitalWrite(2, LOW);
                          digitalWrite(3, HIGH);

                          //delay(i);
                          delayMicroseconds(i*bai);
                          
                          digitalWrite(2, LOW);
                          digitalWrite(3, LOW);

                          delayMicroseconds((10-i)*bai);
                        }

                        for(int i=10;i>0;i--){
                      // +V
                          digitalWrite(2, LOW);
                          digitalWrite(3, HIGH);

                          delayMicroseconds(i*bai);
                          
                          digitalWrite(2, LOW);
                          digitalWrite(3, LOW);

                          delayMicroseconds((10-i)*bai);
                        }

                      // 0V
                        digitalWrite(2, HIGH);
                        digitalWrite(3, LOW);
                        
                        for(int i=0;i<10;i++){
                      // -V
                          digitalWrite(2, HIGH);
                          digitalWrite(3, HIGH);

                          delayMicroseconds(i*bai);
                          
                          digitalWrite(2, HIGH);
                          digitalWrite(3, LOW);

                          delayMicroseconds((10-i)*bai);
                        }

                        for(int i=10;i>0;i--){
                      // -V
                          digitalWrite(2, HIGH);
                          digitalWrite(3, HIGH);

                          delayMicroseconds(i*bai);
                          
                          digitalWrite(2, HIGH);
                          digitalWrite(3, LOW);

                          delayMicroseconds((10-i)*bai);
                        }

                      }


                      ATINY85でLチカする

                      0

                        ATINY85でLチカする

                         

                        JUGEMテーマ:電子工作

                         

                         

                        ■ピン配置

                         

                         

                        ■性能

                         

                        RAM : 512byte
                        ROM : 8Kbyte
                        アナログ入力 : 4 内リセット兼用が1
                        デジタル入出力 : 6 内リセット兼用が1
                        内蔵クロック(最大) : 16.5Mhz
                        PWM : 4

                         

                         

                        ■arduinoIDEにATiny85を追加

                         

                        ファイル→環境設定

                         

                         

                        追加ボードマネージャーのURLにhttp://drazzy.com/package_drazzy.com_index.json
                        OK

                         

                        ツール→ボード→ボードマネージャー

                         


                        atiny85でフィルタ
                        ATTinyCore by Spence Kondeをインストール

                         

                        ■書き込み装置の

                        https://synapse.kyoto/hard/bootloader_sketch/page001.html

                        いつもはATMEGA328の所についているジャンパピン6個をATiny85の所に付け替える。

                        この時電源は入っていないことに注意。

                         

                         

                        ■ボードにATiny85を選択して書き込み

                         

                         

                        ツール→ボード→ATiny25/45/85

                        ツール→ブートローダーを書き込む

                         

                        ■プログラムを書き込む

                         

                         

                        スケッチ→書き込み装置を使って書き込む

                         

                        ■Lチカ

                         

                         


                        ■プログラム

                         

                        void setup() {
                          pinMode(1, OUTPUT);

                        }

                        void loop() {
                          digitalWrite(1, HIGH);
                          delay(1000);
                          digitalWrite(1, LOW);
                          delay(1000);
                        }


                        IM920cを使った920MHz通信の実験2(受信装置側に表示機を付けてみた)

                        0

                          IM920cを使った920MHz通信の実験2(受信装置側に表示機を付けてみた)

                          JUGEMテーマ:電子工作

                           

                          前の記事で
                          http://miha.jugem.cc/?day=20190210

                          次は電波の飛びを測定します。と書いたんですが、
                          パソコンとシリアル接続してモニターしながら家の周りをうろうろするのも結構厳しいなーと言う訳で、
                          受信機側に表示機を付けて送信機の位置を固定して受信機だけを持ってうろうろする作戦にしてみました。

                          それで部品箱に余っていたACM1602NI-FLW-FBW-M01

                          http://akizukidenshi.com/catalog/g/gP-05693/

                          を接続して受信データを表示してみました。

                           

                          ■回路図

                           

                           

                          ■完成図

                           

                          左が送信機。右が受信機

                           

                          ■受信機をZiplockに投入

                           

                          表示機が光っているので透けて見える

                           

                          ■結果

                           

                          □直線道路でのテスト。

                           


                          間に電柱などの障害物はあるが 

                          ゴール地点まで平坦で見通せていた

                          実用的な通信が可能な距離は511m。

                           

                          そこから先に行くと地面が下がっており、

                          そのせいで見通せなくなってしまった可能性があるが、その場合の限界到達点は782m。

                           

                          □建物が障害物になるケース

                           

                          他の実験としては我が家はマンションの5階なんですが、

                          自宅マンションのベランダに送信機を置いてテストを行った。

                          その場合、ベランダの反対側の1階でも安定して通信が可能でした。

                           

                          □建物を突き抜けて通信できるか?

                           

                          自宅マンションは電波が通過したようなんで、

                          周辺のマンションを障害物に見立ててテストした。

                          障害物の量にもよるが

                          わりと障害物が有る方角で100m程度は通信可能。

                           

                          □田舎の山の上に送信機を付けた場合に

                           

                          結構遠くまで電波が飛びそうですが

                          どうなんでしょうねー。

                           

                          ■プログラム

                           

                          □送信側
                          IM920_Sender.ino

                          #include <SoftwareSerial.h>
                          SoftwareSerial mySerial(10, 11); // RX, TX

                          void setup() {
                            Serial.begin(9600); 
                            Serial.println("setup soft serial send count version0.01");
                            mySerial.begin(19200); 
                          }

                           

                          int nCount = 0;
                          void loop() {
                              char szBuf[256];
                              sprintf(szBuf, "TXDA %014d", nCount);
                              mySerial.println(szBuf);
                              Serial.println(szBuf);
                              nCount++;
                              delay(1000);
                          }

                           

                          □受信側

                           

                          IM920_Receiver.ino

                          #include <Wire.h>
                          #include <SoftwareSerial.h>

                          SoftwareSerial mySerial(10, 11); // RX, TX

                          void setup() {
                            Serial.begin(9600); // ハードウェアシリアルを準備
                            Serial.println("Ready version0.01");
                            mySerial.begin(19200); // ソフトウェアシリアルの初期化

                            Wire.begin();       // I2C初期化
                            LCD_begin();
                          }

                          char nCount = 0;
                          char szBuf[256];

                          void loop() {
                            
                            if (mySerial.available()){
                                char c = mySerial.read();
                                Serial.write(c);
                                if(c==0x0d){
                                  strcat(szBuf, "                                ");
                                  LCD_disp(szBuf);
                                  memset(szBuf, 0, sizeof(szBuf));
                                  nCount = 0;
                                }
                                else{
                                  if(c!=0x0a){
                                    szBuf[nCount] = c;
                                    nCount++;
                                    if(nCount>=255){
                                      nCount=0;
                                    }
                                  }
                                }
                                delay(1);
                            }
                            if (Serial.available()){
                              char c = Serial.read();
                              mySerial.write(c);
                              delay(1);
                            }
                          }

                          void LCD_disp(char *str)
                          {
                            byte i;

                            writeCmd(0x80);//1行目
                            delay(5);
                            for(i=0;i<16;i++)
                            {
                              writeData(str[i]);
                              delay(1);
                            }
                            writeCmd(0xC0);//2行目
                            delay(1);
                            for(i=16;i<32;i++)
                            {
                              writeData(str[i]);
                              delay(1);
                            }
                          }

                          void LCD_begin(void)
                          {
                            // LCD初期化
                            delay(15);
                            writeCmd(0x01);//クリア ディスプレイ
                            delay(5);
                            writeCmd(0x38);//8ビットモード、2ライン、5x8ドット
                            delay(5);
                            writeCmd(0x0f);//ディスプレイON、CURSOR-ON、blinking-ON
                            delay(5);
                            writeCmd(0x06);//CURSOR移動、スクロールOFF
                            delay(5);
                            writeCmd(0x80);//ディスプレイON、CURSOR-OFF、blinking-OFF
                          }

                          void writeCmd(uint8_t cmd) 
                          {
                            uint8_t rs_flg;
                            Wire.beginTransmission(0x50);
                            rs_flg = 0x00;
                            Wire.write(rs_flg);
                            Wire.write(cmd);
                            Wire.endTransmission();
                          }

                          void writeData(uint8_t dat) 
                          {
                            Wire.beginTransmission(0x50);
                            Wire.write(0x80);
                            Wire.write(dat);
                            Wire.endTransmission();
                          }
                           


                          IM920cを使った920MHz通信の実験

                          0

                            IM920cを使った920MHz通信の実験

                            JUGEMテーマ:電子工作

                             

                            INTERPLAN社のIM920cが秋月にありますのでこれで
                            通信ができるものを作成して実験しまーす。

                             

                             

                            ますはひととおり調査。

                             

                            ■IM920cのデフォルト設定値

                             

                             シリアル通信速度 19200bps
                            送信出力 10mW
                            無線通信速度 長距離モード

                            このデフォルト設定で見通し距離7Kmで1.25kbpsの通信が可能とのこと。

                             

                            ■IM920cのピン配置

                             

                            6    RxD        TX
                            7    TxD        RX

                            17    MODE1    H
                            18    MODE2    L
                            19    MODE3    L

                            23    VCC        3.3V
                            24    GND        GND 

                             

                            ■IM920c/IM920s用変換アダプターにはピン17,18,19が接続されていない。

                             

                             

                             そもそもIM920cはデータ通信モード専用な様ですんでMODE設定用のPINは不要なのだろう。
                            したがって変換アダプタのピンで以下で良いだろう。
                            ADP        arduino
                            J2の3    RxD        TX
                            J1の4    TxD        RX
                            J1の9    VCC        3.3V
                            J2の9    GND        GND 

                             

                            ■IM920cのコマンド

                             

                             RDID 送信モジュール固有のID番号表示
                             
                             ENWR 書き込み許可
                             
                             SRID 受信側モジュールに送信モジュールIDを書き込み
                              SRID 送信モジュールID

                             

                             ERID 登録済みの送信モジュールIDを全部削除
                             
                             RRID 登録済みの送信モジュールID読み出し
                             
                             STPO 送信電力設定
                              STPO 送信電力
                              
                             RDPO 送信電力読み出し
                              1: -10dBm (0.1mW)、 2: 0dBm (1mW)、 3: 10dBm (10mW)
                             
                             STRT 無線通信速度設定
                              STRT 無線通信速度
                              
                             RDRT 無線通信速度読み出し
                              1:高速通信モード(無線通信速度 50kbps)、2:長距離モード(無線通信速度 1.25kbps)

                             

                             TXDT データ送信
                              TXDT 0123456789ABCDEF

                             

                             RPRM パラメータ一括読み出し
                             
                             
                            ■接続図

                             

                            PC(COM4接続)-USBUART変換-Arduino-IM920c
                              --無線920MHz--USBUART変換-
                              IM920c-Arduino-PC(COM4接続)

                             

                            ■COM4に接続したIM920CからCOM5に接続したIM920Cに送信

                             

                            ◇COM5側にCOM4のモジュールIDを設定

                             

                            ENWR
                            SRID 5E70
                            RRID

                             

                            ◇COM4側からデータ送信

                             

                            TXDT 0123456789ABCDEF

                             

                            ◇COM5側に以下表示される

                             

                            00,5E70,D8:01,23,45,67,89,AB,CD,EF

                            CSV形式で表示されている意味は
                            00:送信側のノード番号 デフォルトは00
                            5E70:送信側のモジュールID
                            D8:RSSI値 電波の強さ
                            01,23,45,67,89,AB,CD,EF:受信したデータ
                            データはTXDTで送信した場合は16バイト送信される

                             

                            ◇データサイズを変えて色々入れてみる

                             

                                TXDT 01020304050607
                                →00,5E70,D8:01,02,03,04,05,06,07,00

                             

                                TXDT 010203040506
                                →00,5E70,D7:01,02,03,04,05,06,00,00

                             

                                TXDT 0102030405
                                →00,5E70,D9:01,02,03,04,05,00,00,00

                             

                                TXDT 01020304
                                →00,5E70,D8:01,02,03,04,00,00,00,00

                             

                                TXDT 010203
                                →00,5E70,D9:01,02,03,00,00,00,00,00

                             

                                TXDT 0102
                                →00,5E70,D7:01,02,00,00,00,00,00,00

                             

                                TXDT 01
                                →00,5E70,D8:01,00,00,00,00,00,00,00

                             

                                TXDT 0
                                →00,5E70,D8:00,00,00,00,00,00,00,00

                             

                                TXDT 1
                                →00,5E70,D8:00,00,00,00,00,00,00,00

                                ??ん1バイトだけだと1バイト目が捨てられた
                             

                                TXDT 123
                                →00,5E70,D8:12,00,00,00,00,00,00,00
                                ??ん3バイトだと3バイト目が捨てられた

                             

                                TXDT 
                                →00,5E70,DA:00,00,00,00,00,00,00,00
                                
                                ※送信のされ方まとめ

                             

                                 ルール1 16バイト単位で送信される
                                  TXDTだけでも16バイト送られる。
                                  その場合は中身は全部ゼロ
                                  偶数バイト送信した場合は偶数バイトのデータは届くが
                                  16バイトになるまでの部分はゼロで埋められる

                             

                                 ルール2 奇数バイト送信した場合最後の1バイトは捨てられる
                                  つまり、
                                   1バイトの場合はその1バイトが捨てられる
                                   3バイトの場合は3バイト目が捨てられる
                                   5バイトの場合は5バイト目が捨てられる
                                   以下同じ
                                結構特殊っすね。
                                  
                            ■TXDTじゃなくTXDAで送信

                             

                                TXDA
                                →00,5E70,D8:

                             

                                TXDA 1
                                →00,5E70,D8:

                             

                                TXDA 12
                                →00,5E70,D8:12

                             

                                ※ここまでTXDA16バイト単位ルールが採用されていたがそのルールはない事が判明
                                 奇数バイトの最後は捨てられるのは同じ

                             

                                TXDA ABCDEFGHIJKLMN
                                →00,5E70,D8:12,34,56,78,90,F1,DA,AB,CD,EF,11,33,55,77
                                ※16進数しか送れない これはTXDAと同じ

                             

                                TXDA 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
                                →00,5E70,D8:01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89,01,23,45,67,89
                                ※100バイト送っても平気。
                                こっちのほうが使えそう。
                                説明書には64バイト可変長ってなっているけどね。
                                64バイトに抑えて使ったほうが良さげっすね。


                            ■プログラム

                             

                            #include <SoftwareSerial.h>
                            SoftwareSerial mySerial(10, 11); // RX, TX

                            void setup() {
                              Serial.begin(9600); // ハードウェアシリアルを準備
                              while (!Serial) {
                                ; // シリアルポートの準備ができるのを待つ(Leonardoのみ必要)
                              }
                              Serial.println("Ready version0.01");
                              mySerial.begin(19200); // ソフトウェアシリアルの初期化
                            }

                            void loop() {
                              if (mySerial.available()){
                                  char c = mySerial.read();
                                  Serial.write(c);
                            //      Serial.println(int(c));
                                  delay(1);
                              }
                              if (Serial.available()){
                                char c = Serial.read();
                                mySerial.write(c);
                                delay(1);
                              }
                            }

                             

                            使い方は簡単でteratermでArduinoに9600bps接続します。

                            IM920c側の通信速度を19200bpsのデフォルトのまま使っているんですが、

                            これだとIM920c側からのデータが取りこぼされて

                            文字化けが発生したんですが、delay(1)を挟んで調整しています。

                             

                            本日はここまで。
                            時間があれば、どこまで電波が飛ぶか実験してみますね。

                             

                            以下は電波がどこまで飛ぶか実験のための準備

                             

                            ■電波飛び測定用送信機側プログラム

                             

                            #include <SoftwareSerial.h>
                            SoftwareSerial mySerial(10, 11); // RX, TX

                            void setup() {
                              Serial.begin(9600); 
                              Serial.println("setup soft serial send count version0.01");
                              mySerial.begin(19200); 
                            }

                             

                            int nCount = 0;
                            void loop() {
                                char szBuf[256];
                                sprintf(szBuf, "TXDA %016d", nCount);
                                mySerial.println(szBuf);
                                Serial.println(szBuf);
                                nCount++;
                                delay(1000);
                            }

                             


                            ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 最終回

                            0

                              ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 最終回

                              JUGEMテーマ:電子工作

                               

                              どこから買ったのかも忘れましたけどdynabook-SatelliteL21に出会い
                              確か8000円ぐらいで何が来るのかお楽しみ的なショップから。

                              到着したのが
                              インテル Celeron搭載のメモリ2GでHDD160GB
                              CPUはCeleron900 2.20GHz
                              これにWindows10が入った状態でした。

                               

                              youtube見るのも時々止まる様な感じ結構ストレスありました。
                              とりあえず、メモリスロットが一つ空いていたのでこのマシンでの最大の4GBにして
                              しばらく使っていたんですが、
                              別のメインにしているマシンにグラボ付けたら
                              BUFFALOのDT-H70-U2でテレビが映らなくなり。
                              グラボはGT1030ね。

                               

                              それでは、
                              という事でこのdynabook-SatelliteL21さんにテレビになって頂くという事で
                              ドライバーやTVソフトなどインストールして
                              やってみたんですが、いまいち快適でなく。
                              固まったり固まったり。

                               

                              CPU交換に挑戦しておりました。

                               

                              前々の記事 http://miha.jugem.cc/?eid=193
                              前の記事 http://miha.jugem.cc/?eid=198

                              色々試行錯誤有りましたがすごく勉強になりました。

                               

                              ■前々の記事の時は単純にTOSHIBAのページに載っていた上位マシンに搭載されているCPU

                               

                              Core 2 Duo P8700で行けるかと思い実行に移すもFSBが異なり撃沈

                              その後記事にはしておりませんが
                              どこかの勇者さんのページでCore 2 Duo T7600で行けそうという情報があったので
                              こちらに挑戦するもSocketとFSBが異なりまたも撃沈。

                              これでは駄目だと思い調べまくりました。

                               

                              ■前の記事ではいちおうキチンと学習して


                              勇者のページに記載されていた
                              http://www.cpu-upgrade.com/mb-Intel_(chipsets)/index.html
                              同じチップセットで動作するCore2Duo T7250を入手。
                              実際に乗せてみたところ、動作はするんですが、
                              なぜかファンが最大出力で回転し続けるという罠にはまってしまいました。

                              勇者のページで学んだ要素の中で元々のCeleron900とT7250で異なっていたのは
                              CPUコア名(Celeron900:Penryn、 T7250: Merom)
                              プロセスルール(Celeron900:45 nm、 T7250: 65 nm)
                              つまり、そこまで合わせればOKって事ね。

                               

                              ■またまた入手。


                              という事で今回手に入れたのが
                              Core2Duo T8100
                                  socket PBGA479, PPGA478 Socket P
                                  2core
                                  3Mキャッシュ、2.1GHz  800MHzFSB
                                  35W
                                  製品の開発コード名 Penryn
                                  プロセスルール 45 nm
                              CPUのクロックも同じ。

                               

                              右がCore2Duo T8100

                               

                              これであっさりうまく行きました。
                              ファンも元通り静かになりましたし
                              テレビも快適に見ています。

                               

                              ■結果

                               


                              ■性能評価

                               

                              (celeron900との比較)
                              全体性能で44%UP
                              CPUは91%UP
                              メモリーは17%UP
                              他は若干上がるか若干下がるかという結果。

                              使用感としては全く別物という感じです。

                               


                              ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 成功

                              0

                                ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 成功

                                 

                                前の記事の続き。
                                http://miha.jugem.cc/?eid=193

                                 

                                ポチっておいたCPU Core2Duo T7250が届いたので
                                続きを書きます。

                                 


                                前回書ききれなかった所を書いていきます。

                                 

                                見えているねじを外しても全部ではなくて
                                隠れているねじがあります。光学式ドライブの下とHDDの下になります。


                                まず、見えているねじを全部外してから以下を行います。

                                 

                                光学式ドライブの外すには
                                クリップの針金を光学式ドライブの穴に入れるとカチッと音がして

                                蓋が空きます。開いたら引っ張れば外れます。

                                 

                                 


                                そしてその下にねじがあります。

                                 

                                 

                                HDDの下です。

                                 

                                 

                                キーボードを外して白いシートをはがすとマザーボードとコネクタが見える.

                                 

                                 

                                 

                                このコネクタを外していく。
                                5か所ある。

                                他は前回と同じ。

                                 

                                上がT7250

                                下がCeleron900

                                 

                                 

                                結果

                                 

                                 

                                 

                                ■評価

                                 

                                全体性能は30%UP

                                CPUは60%UP

                                メモリーは17%UP

                                他は若干上がるか若干下がるかという結果。

                                使用感としては

                                倍ぐらいの速度が出ている感じがします。

                                BUFFALOのDT-H70-U2のTV視聴を快適にするという目的は達成しており、

                                TV視聴中のCPU使用率は20%〜30%前半で推移しており、

                                チャンネル切り替えでもハングアップすることは

                                全くなくなりました。

                                 

                                ただ、CPU冷却ファンが全力回転して騒音が発生しております。

                                TV視聴には少々快適とは言えません。

                                 

                                ■以下CPU選びの反省色々メモ。

                                 

                                前回失敗していたCPUの選択について。
                                色々判りましたのでメモ。

                                情報として記録しておきます。

                                satellite L21 TOSHIBAのページの情報
                                    モバイル インテルR GL40 Expressチップセット
                                    システムバスクロック/メモリバスクロック800MHz/800MHz
                                    メモリPC2-6400(DDR2-800)対応 SDRAM 2GB/4GB

                                GL40 Express Intelのページの情報
                                    インテルR 4 シリーズ・チップセット
                                    FSB 667MHz
                                    最大メモリーサイズ (メモリーの種類に依存)    4 GB
                                    メモリーの種類    DDR2 667
                                    最大メモリーチャネル数    2
                                    物理アドレス拡張    36-bit
                                    ECC メモリー対応    いいえ
                                    内蔵グラフィックス    はい
                                    グラフィックス出力    LVDS, SDVO, TV Out, CRT
                                    インテル クリアー・ビデオ・テクノロジー    いいえ
                                    サポートされているディスプレイ数     2
                                    PCI Express リビジョン    1.1
                                    PCI Express 構成    1x16

                                GL40 Express Wikiのページ
                                    FSB 800/667MHz、DDR2-800/667, DDR3-800/667をサポート。最大メモリ容量は8GB。
                                    Intel Graphics Media Accelerator X4500HD(GMA 4500M)を内蔵。

                                TOSHIBAによるとFSBは800MHz、IntelによるとFSBは667MHzと異なる。
                                Wikによると両方書いているのと、Celeron900がFSB800MHzとあるので
                                FSBは800MHzとする。

                                チップセットとCPUの対応
                                    勇者がCPU交換の成功自慢をしているページ
                                        http://www.cpu-upgrade.com/mb-Intel_(chipsets)/index.html
                                    
                                    GL40はこちら。
                                        http://www.cpu-upgrade.com/mb-Intel_(chipsets)/GL40_Express.html
                                        ここのページに大事な事が書いてある。
                                        「以下はGL40 Expressチップセットのサポートリストです。
                                         あなたのマザーボードのサポートリストではありません。
                                         チップセットは、CPUの互換性を左右する重要な要素の1つにすぎません。
                                         その他の重要な要素は、ソケットの種類、パッケージの種類、最大のThermal Design Power、
                                         BIOSのバージョン、CPUコア名、およびステッピングです。 
                                         そのため、チップセット上に構築されたすべてのマザーボードが、
                                         リストされたすべてのプロセッサと互換性があるわけではありません。 
                                         あくまでも目安としてこのリストを使用してください。」
                                        つまり、博打ってこと。当たるも外れるも自己責任。
                                    これを見ると
                                        Core2DuoであればT7250とT7300が大丈夫そう。
                                        T7250は円以内で入手可能。
                                    さらにここのページで次の情報も入手
                                        CPU support summary
                                        Codename: Merom, Penryn
                                        Technology: 0.045, 0.065 micron
                                        Cores/Threads: 1 - 2
                                        Frequency: 1667 - 2300 MHz
                                        L2 cache: 1024 - 4096 KB
                                        TDP:31 - 35 Watt

                                SocketPについて
                                    Yahoo知恵袋などによると
                                    GL40 ExpressはSocketPとの情報があり。
                                    情報元がよく判らんのだけど
                                    wikiによるSocketPの情報
                                        ソケット形式    PGA
                                        チップ形状    FC-PGA
                                        コンタクト数    478
                                        FSB    400MT/s, 533MT/s, 667MT/s, 800MT/s, 1066MT/s
                                        採用プロセッサ
                                            Intel Core 2 Duo (T5xx0, T7xx0, T8x00, T9x00)
                                            Intel Core 2 Quad (Q9100, Q9000)
                                            Intel Celeron(5xx, 9xx, Tシリーズ)
                                            Intel Pentium Dual-Core (T23x0, T2410, T3x00, T4200)
                                    他のmobile用のは
                                        Socket 495 Socket 479 Socket M Socket P Socket G1 Socket G2 Socket G3
                                            があるという。
                                    世代が近いのがSocketMで以下に情報を載せる
                                        ソケット形式    PGA
                                        チップ形状    FC-PGA
                                        コンタクト数    478 (以前のSocket 479とは異なる)
                                        FSB    533 MT/s, 667 MT/s, 800MT/s
                                        採用プロセッサ
                                            Intel Core Solo
                                            Intel Core Duo
                                            Intel Core 2 Duo (T5x00, T7x00, T8x00)
                                            Intel Celeron M(4xx, 5xx)

                                GL40 ExpressがSocketPとわかる情報が見つからない件
                                    よくわからんけど上記のWikiのSocket毎のCPUの対応で
                                    「Celeron900が搭載されていればSocketPで良い」と決定した。

                                色々調べた所の結論。各CPUの詳細は下記

                                数々の勇者に調べにより core2duoであればT7250とT7300が候補で
                                T7250は1000円以下で入手可能。
                                勇者のページに掲載されている他の要素
                                    チップセット : OK
                                    ソケットの種類 : OK
                                    パッケージの種類 : OK
                                    最大のThermal Design Power : OK
                                    BIOSのバージョン : 博打
                                    CPUコア名 : Penryn → Merom 異なる
                                    ステッピング : どうやって調べる?
                                で概ねOKの様です。

                                Celeron 900
                                    socket PGA478
                                    1core
                                    1Mキャッシュ、2.20GHz、800MHzFSB
                                    35W
                                    製品の開発コード名 Penryn
                                    プロセスルール 45 nm

                                購入履歴

                                # ボツ TOSHIBAのページの上位機種がP8700だったので試したがFSBが異なり撃沈
                                # Core 2 Duo P8700 2.53GHz FSB1066MHz SLGFE
                                #     socket BGA479, PGA478, Socket P
                                #     2core
                                #     3Mキャッシュ、2.53GHz、1066MhzFSB
                                #     25W
                                #    製品の開発コード名 Penryn
                                #    プロセスルール 45 nm

                                    
                                # ボツ どこかサイトでこれで行けると記事が有ったので試したがこれはSocketとFSBが異なり撃沈
                                #Core 2 Duo T7600 2.33GHz FSB667MHz Merom SL9SD
                                #    socket PBGA479, PPGA478, Socket M
                                #    2core
                                #    4Mキャッシュ、2.33GHz、667MHzFSB
                                #    34W
                                #    製品の開発コード名 Merom
                                #    プロセスルール 45 nm

                                 

                                 

                                 

                                #採用
                                Core 2 Duo T7250 2.0GHz 2MB L2 Cache 35W Dual Core CPU SLA49 BX80537T7250
                                    socket PBGA479, PPGA478 Socket P
                                    2core
                                    2Mキャッシュ、2.0GHz  800MHzFSB
                                    35W
                                    製品の開発コード名 Merom
                                    プロセスルール 65 nm


                                ペルチェ素子で冷え冷え実験

                                0

                                  ペルチェ素子で冷え冷え実験

                                   

                                  JUGEMテーマ:電子工作

                                   

                                  なんでこんな1月の寒いときに冷え冷え実験なのかといいますと、
                                  今住んでいる東京のアパートは最上階の為か
                                  夏に家に帰ってくると温度が37度とかになっております。
                                  当然、そこにおいてあるお菓子とか、薬とかは品質に問題が生じている恐れがあり
                                  どれも使用できない事になります。

                                  かといって冷蔵庫も一人暮らし用のアパートではそんなに大きなものも置けないので、
                                  なんとか冷え冷えスペースを確保したいと考えておりました。

                                  で、発泡スチロールにペルチェ素子を組み込んで
                                  ほどほどに冷える冷え冷え箱を作成したいともくろんでおり、
                                  共立電子から仕入れておりましたので
                                  基礎実験を行います。
                                  http://eleshop.jp/shop/g/g22A132/

                                   

                                  ■目標

                                  作成目標としては、カラーボックス1段分ほどの大きさの箱の中を27℃を
                                  超えないように制御する。

                                   

                                  ■実験

                                  今回は基礎実験という事で、温度制御機構を除くペルチェ素子の使い方だけを実験します。

                                  色々試してみたのですが、
                                  単純にペルチェに電圧を与えるだけではダメで
                                  電圧を与えると片面熱くなり、片面冷えるのですが、
                                  そのうち両方熱くなるんです。熱が伝わってきてしまうようです。

                                  では、ヒートシンクというわけで一緒に買っておいたヒートシンクを両面に取り付けてみた。
                                  この場合は何もしない状態よりはましですが、時間がたつとやはり両面熱くなります。
                                  熱くなるほうは触れないぐらい熱いのでペルチェの冷え冷え機能自身は働いている。

                                  次に、PC用冷却ファンで熱い面のヒートシンクを放熱させてみます。
                                  そのまの状況では風が両方に吹いてくるのでよくわからない状況になりましたので、
                                  20センチぐらいの段ボールの真ん中にペルチェ素子の大きさで四角く穴をあけて
                                  そこにすっぽり入るように重ねます。

                                  その状態で試すとよろしい結果になります。冷たい面のヒートシンクが冷え冷えです。

                                  以下のようなサンドイッチ状態になります。

                                   

                                  こっちが冷たくなる
                                     ↑
                                   ヒートシンク
                                   風を遮るための段ボール
                                   ペルチェ素子
                                   ヒートシンク
                                   PC用冷却ファン
                                   PC用冷却ファンの風が通るように空間をあける(箱)
                                     ↓
                                  こっちが熱くなる

                                   

                                  ■以下写真でご確認ください。

                                   

                                  □PC用冷却ファンの風が通るように空間をあける為に箱を置く

                                   

                                   

                                  □その上にPC用冷却ファンを置く

                                   

                                   

                                  □その上にヒートシンクを置く

                                   

                                   

                                  □その上にペルチェ素子を置く

                                   

                                   

                                  □さらに 風を遮るための段ボール(真ん中にペルチェと同じ大きさの四角い穴開け済み)

                                   

                                   

                                  □ペルチェ素子の上にヒートシンクを置く

                                   

                                   

                                  ヒートシンク冷え冷えです。

                                   

                                  ちなみに、ペルチェ素子の定格を超えない様に12Vの電圧をかけています。

                                  PC用冷却ファンは定格を超えた15Vかけています。

                                   

                                  ■その先にあるもの

                                   

                                  実際の実装は丁度いい発泡スチロールが手に入ってから。
                                  マイコンで温度測定してスイッチON/OFFですね。


                                  ソーラーパネルとENELOOPのハイブリッド電源

                                  0

                                    ソーラーパネルとENELOOPのハイブリッド電源

                                     

                                    回路図
                                     

                                     


                                    実際に回路を組んで実際に電圧と電流を測定した結果を記入しています。
                                    Output側にはArduinoの5V-16MHz版を接続してLチカを動作させています。

                                     

                                    参考
                                    https://blogs.yahoo.co.jp/jf1vrr_station/21398456.html

                                     

                                    ■ソーラーパネル側からの供給


                                    直射日光の下ではソーラーパネルからは6.8V、63mAが供給されている模様。
                                    それを秋月の5V昇圧型DCDCコンバーター5V版(M-03451)に入れると6.4Vが取り出せます。
                                    秋月のページによると入力電圧範囲が0.7〜5.0Vとなっているので定格オーバーですが、
                                    ここは頑張ってもらうこととします。
                                    それを1N4007で0.7V降下した5.7Vを3端子レギュレーターに入れて3.3Vを取り出しています。

                                     

                                    ■Eneloop側からの供給


                                    Eneloop4本直列で4.8Vから19mA取り出しています。
                                    それを1N4007で0.7V降下した4.2Vを3端子レギュレーターに入れて3.3Vを取り出しています。

                                     

                                    ■Eneloopへの充電


                                    キーワードはトリクル充電。
                                    充電するときは電池に対して1.14倍の電圧をかける。
                                    充電するときは電池の容量の10%の電流で充電する。
                                    記事がありましたのでそれを参考にしまして、
                                    ソーラーパネルから取り出した6.4Vを1N4007で降圧して5.7Vにして(もう一個ダイオード入れたほうが安全だろうか?)
                                    さらに抵抗で30Ωを入れて(実際には10Ω-1Wを3個直列)電流を200mA以上流れないように調整しています。
                                    電池の容量は2100mAhなので210mAまでならOKなはず。
                                    Eneloopと言っているが実際に使っているのは秋月で入手したGoldenPowerの単3電池です。
                                    実際の測定では18mAぐらいで充電されている模様ですが、これはEneloop側が既に満杯になっている可能性もあります。
                                    本来であればEneloop側の電圧を測定しながら充電および放電を制御するのが正しいやり方なんですが、
                                    電池の寿命を気にしない人は自己責任でこんな回路でもarduinoぐらいなら動かせると思います。
                                    トリクル充電なんで普通にバッテリー寿命は延びると思うんだけどねー。

                                     

                                    ■評価


                                    ソーラーパネルからの電力供給で
                                    どのぐらいの電力が取り出せるのか実験です。
                                    実験の仕方としては負荷として10Ω、1Wの抵抗を直列または並列で接続して
                                    Arduinoが動かなくなるギリギリの電流を探していきます。
                                    というわけで、Arduinoはそのまま接続して追加の負荷として抵抗を接続していきます。
                                    ちなみに、ここではソーラーパネルのみでの運用としてEneloopを外して実験します。
                                    10Ωをひとつだけ接続 → arduinoが動かない。
                                    10Ωをふたつ接続  → arduinoが動かない。
                                    10Ωをみっつ接続  → 動いた。30Ωって事は100mAだね。
                                    実際の測定結果
                                    Output側
                                    3.26V、99.8mA
                                    = 0.3W
                                    ソーラーパネルからの供給
                                    5.9V、103.4mA
                                    = 0.6W
                                    効率が非常に悪いですね。

                                     


                                    ArduinoでDeepSleepを利用する

                                    0

                                      JUGEMテーマ:Arduino

                                      ArduinoでDeepSleepを利用する

                                      ■実際の消費電流の測定



                                      実際の電流を測定しています。
                                      テスターはマイクロアンペアのモードです。
                                      起動直後大き目の電力が流れてその後
                                      6μA〜7μAぐらい消費します。DeepSleepしています。
                                      スリープは8秒毎に解除される、のでその時に赤いLEDをピカッと光らせます。
                                      Sleepから復帰して赤いLEDを光らせるために一瞬電流が多く流れます。
                                      LEDを光らせた後に再びsleepに入ります。
                                      3回繰り返した後に緑のLEDを1秒間光らせます。
                                      この時も電流が多く流れます。

                                      ■プログラム解説
                                       
                                       □loopの開始と終了に20ミリ秒のdelayを入れています。
                                        これはsleep復帰後すぐにSerial通信をすると文字化けしてしまうためです。

                                       □watchDogSleep();
                                        これがSleepのメインになります。
                                        消費電力を抑えるにはなるべく長くsleepさせておいたほうが良いと考え指定できる最大の8秒sleepさせます。
                                        でも、もっと長くsleepさせたいので回数を指定するようにしてsleep→復帰→sleepを繰り返すようにています。
                                        
                                        ループの中で実際のDeepSleepと復帰処理を行います。
                                        
                                       □パワーダウンモードを設定 SM1 パワーダウンモード
                                       
                                         SMCR |= 0b00000001 | 0b00000100;
                                       
                                       □AD変換機能をOFFにする ADEN 復帰後ONにする
                                       
                                        ADCSRA &= ~(0b10000000); //ADコンバーターEnableをOFF
                                        
                                       □おっちドッグタイマーをセットする
                                       
                                        asm("wdr");
                                        WDTCSR |= 0b00011000; //WDCE WDE おっちドッグタイマー設定モード
                                        //WDTCSR = 0b01000000 | 0b000110;// 1 秒
                                        //WDTCSR = 0b01000000 | 0b000111;// 2 秒
                                        //WDTCSR = 0b01000000 | 0b100000;// 4 秒
                                        WDTCSR = 0b01000000 | 0b100001;// 8 秒
                                       
                                       □低電圧検出器を停止する(スリープの間有効)
                                       
                                        MCUCR |= 0b00100000 | 0b01000000;  //BODSE BODS
                                        MCUCR = (MCUCR & ~(0b00100000)) | (0b01000000); //BODSE BODS
                                        
                                       □スリープする。 指定した時間で戻る 上記の低電圧検出器を停止の流れで実施
                                       
                                        asm("sleep");
                                       
                                       □おっちドッグタイマーを停止する
                                       
                                        asm("wdr");
                                        MCUSR &= ~(0b00001000);          //おっちドッグタイマーリセットフラグをOFF WDRF
                                        WDTCSR |= (0b00010000)|(1 << 0b00001000); //おっちドッグタイマー設定変更 WDCE WDE
                                        WDTCSR = 0b00000000;           //おっちドッグタイマー停止
                                       
                                       □AD変換機能をONにする
                                       
                                        ADCSRA |= 0b10000000;   //ADENをON

                                       □ISR(WDT_vect)
                                       
                                         赤いLEDをピカッと光らせます


                                      ■プログラム

                                      void setup() {

                                        Serial.begin(9600);
                                        Serial.println("ver1.0");
                                        Serial.println("start:");

                                        pinMode(4, OUTPUT);
                                        pinMode(13, OUTPUT);

                                      }

                                      #define sleep_time 20

                                      void loop() {
                                        //
                                        //loop関数開始のログ出力
                                        //
                                        delay(sleep_time);  //
                                        Serial.println("loop start:");
                                        delay(sleep_time);  //

                                        //
                                        //緑のLEDをピカッと光らせる
                                        //ここにプログラムを書く
                                        //
                                        digitalWrite(4, HIGH);
                                        delay(100);
                                        digitalWrite(4, LOW);

                                        //
                                        //ウォッチドッグタイマーでスリープする 8秒×3=24秒
                                        //
                                        watchDogSleep(3);

                                        //
                                        //おっちドックタイマーから復帰のログ出力
                                        //
                                        delay(sleep_time);
                                        Serial.println("loop end:");
                                        delay(sleep_time);
                                      }

                                      //watchdog interrupt
                                      ISR(WDT_vect){
                                        digitalWrite(13, HIGH);
                                        delay(100);
                                        digitalWrite(13, LOW);
                                      }

                                      void watchDogSleep(int count)
                                      {
                                        //
                                        //おっちドッグタイマーが最大8秒しかできないので
                                        //1秒設定にしてループする
                                        //
                                        for(int i=0;i<count;i++){
                                          // パワーダウンモードを設定 SM1
                                          SMCR |= 0b00000001 | 0b00000100;
                                        
                                          // AD変換機能をOFFにする ADEN
                                          ADCSRA &= ~(0b10000000);  //
                                          
                                          // おっちドッグタイマーをセットする
                                          asm("wdr");
                                          WDTCSR |= 0b00011000; //WDCE WDE set
                                          //WDTCSR =  0b01000000 | 0b000110;// 1 sec
                                          //WDTCSR =  0b01000000 | 0b000111;// 2 sec
                                          //WDTCSR =  0b01000000 | 0b100000;// 4 sec
                                          WDTCSR =  0b01000000 | 0b100001;// 8 sec
                                        
                                          // 低電圧検出器を停止するスリープの間有効
                                          MCUCR |= 0b00100000 | 0b01000000;   //BODSE  BODS
                                          MCUCR = (MCUCR & ~(0b00100000)) | (0b01000000); //BODSE  BODS
                                          
                                          //スリープ 指定した時間で戻る
                                          asm("sleep");
                                        
                                          // おっちドッグタイマーを停止する
                                          asm("wdr");
                                          MCUSR &= ~(0b00001000);                   //おっちドッグタイマーリセットフラグをOFF WDRF
                                          WDTCSR |= (0b00010000)|(1 << 0b00001000); //おっちドッグタイマー設定変更 WDCE WDE
                                          WDTCSR = 0b00000000;                      //おっちドッグタイマー停止
                                        
                                          // AD変換機能をONにする
                                          ADCSRA |= 0b10000000;     //ADEN
                                        }
                                      }


                                      NoIRのパイカメラと普通のパイカメラの比較実験

                                      0

                                        NoIRのパイカメラと普通のパイカメラの比較実験

                                         

                                        普通のパイカメラを持っていて監視カメラ用途として使用したいと思ってたんですが
                                        これ夜になると真っ黒にしか映りません。
                                        で、赤外線カメラなら夜でもくっきりなのかもと思い、NoIRのラズパイカメラを入手して実験してみた。

                                         

                                        ■普通のラスパイカメラ


                                        ■NoIRのラズパイカメラ


                                        ■NoIRで撮影
                                         写真1 赤外線LEDを撮影 明るい部屋


                                        ■NoIRで撮影
                                         写真2 赤外線を照射して撮影 暗い部屋


                                        ■ラズパイカメラで撮影
                                         写真3 赤外線LEDを撮影 明るい部屋

                                         

                                        ■ラズパイカメラで撮影
                                         写真4 赤外線を照射して撮影 暗い部屋

                                         

                                        ■使用した赤外線照射器

                                        秋月で仕入れた赤外線LED 940ナノmのやつで


                                        規格上は100mAしか流せないので
                                        今回は5Vに47Ωを接続して流したのでほぼ規格通り光らせて2発です。
                                        光が圧倒的に弱いのでこんな感じなりました。


                                        ■結果考察
                                        □NoIRの評価
                                         NoIRの場合は色がおかしい。そういうもんなんだろう た・ぶ・ん・
                                         青い帽子が紫になり緑の綾鷹がくすんで見える
                                         NoIRでは赤外線LEDが光っているのが判り、赤外線を照射している部分は写真にも撮影できる


                                        □普通のラズパイカメラ
                                         普通だな。
                                         ただし、ほぼ真っ暗な環境でも人間に目程度には撮影できている。
                                         むしろNoIRに比較してこちらのほうが見えている。
                                         ちなみに、微妙にLEDが光っているようにも見える。人の目よりは広い範囲が撮影できている感じです。

                                        JUGEMテーマ:電子工作


                                        □総合
                                         監視カメラとして真っ暗でも撮影したい場合はNoIRで赤外線を強力に照射すれば行けそうです。
                                         普通のカメラとして使う分には普通のパイカメラが良いですね。

                                         

                                        ■実験風景

                                         

                                         

                                        ■ラズパイのプログラムはこちら前と同じ。手抜き。

                                         

                                        import picamera
                                        import datetime
                                        import os

                                        #ディレクトリとファイル名を作成
                                        now = datetime.datetime.now()
                                        base_directory = '/home/pi/picamera/data/'
                                        YYYYMMDD = now.strftime('%Y%m%d')
                                        output_directory = base_directory + YYYYMMDD
                                        if not os.path.exists(output_directory):
                                          os.makedirs(output_directory)
                                          os.chmod(output_directory, 0777)
                                        filename = now.strftime('%H%M%S')
                                        filename_fullpath = output_directory + '/' + filename + '.gif'

                                        #カメラを起動して保存
                                        camera=picamera.PiCamera()
                                        camera.hflip = True
                                        camera.vflip = False
                                        camera.resolution = (640,480)
                                        camera.capture(filename_fullpath)

                                        camera.close()


                                        ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 失敗

                                        0

                                          JUGEMテーマ:電子工作

                                          ノートパソコンTOSHIBA-dynabook-SatelliteL21のCPU交換 失敗

                                          東芝のノートパソコン dynabook-SatelliteL21を入手した。
                                          パソコンでテレビを映すためのBUFFALOのDT-H70-U2を接続してテレビを楽しんでおりましたが
                                          最近のWindowsUpdateのせいなのか映らなくなってしまいました。
                                          もともとチャンネル切り替えで固まったり調子が悪かったんでCPUの性能が追い付いていないのかなー
                                          と思いまして、CPUを交換する事にしました。

                                          で、調査。
                                          https://dynabook.com/pc/catalog/satellit/091110l2/spec.htm
                                          TOSHIBAのページによると
                                          同じラインナップでCore? 2 Duo P8700が付いているのがあり、
                                          それの値段が中古で1000円ぐらいでしたので速攻でポチっておいたものが
                                          届いたので

                                           


                                          交換の記録。


                                          裏面
                                           バッテリー、メモリー、ハードディスク、光学ドライブを外す
                                           ついているねじを全部外す

                                           

                                          ねじの位置が判るように綺麗に並べてあります。


                                          表面
                                           電源が付いているパネルを外す
                                            ここはねじが無くてくっついていつだけなのでマイナスドライバーでこじりながらバリバリと外す。
                                            キーボードが取れているのはここらへんで何かがくっついていつみたいだったので
                                            外してみただけー
                                            丸の所にねじがあるのでそれも外す

                                           

                                           


                                          キーボードのねじを外して
                                           キーボードを外す。

                                           



                                          上下に分ける
                                           底のパーツ黒とその上のパーツ銀の間をマイナスドライバーでこじって開ける
                                           コネクターが付いているので外す。
                                           

                                           

                                           後で見るとキーボードを外した時に白いパネルをはがして
                                           そこに見えるコネクターを全部外せばコネクターは全部外れて
                                           きれいに取れる事が判る。

                                           



                                          マザーボードを外していく
                                           マザーボードのねじを外して
                                           裏面にCPUが付いていると思われる部分が見える
                                           

                                           

                                           クーラーを外すとCPUがお目見えする。

                                           


                                          CPUを交換
                                           マイナスドライバーでねじを緩めてCPUを交換。
                                           後は元通りに組みなおす。
                                           左が元々ついていたやつ
                                           →が1000円で買ったやつ

                                           

                                           

                                          電源ON
                                           動かない。

                                           

                                           

                                          同じ手順で元のCPUに付け替える。
                                           電源ON
                                           動く。

                                           

                                           

                                          手順は正しいと思われ。

                                          脳みそが固まって悩んで、もう一度調査。

                                          最初に見た東芝のページによると

                                           

                                           


                                          上位モデルのP8700を搭載しているものはチップセットが違うくて
                                          ・・・つまり、
                                          P8700はそのまま載せ替えられないっぽい

                                          で、必要なCPUはこちら
                                           Core 2 Duo モバイル T7600 2.33GHz FSB667MHz Merom SL9SD
                                           との事らしい。
                                           値段も4600円と前の4倍。
                                           古い製品で性能も悪いのにねー
                                           でも乗り掛かった舟だしポチっておいた。
                                           続きはまた来週かな。

                                           

                                          後日談 2019-1-15

                                          昨日ポストにポチッとして置いたヤツガ届いたので

                                          載せ替えてみたところ、

                                          動かない。

                                          なぜ?

                                           

                                          CPU交換にこれ以上時間をかけてもいられないし。

                                          OSをWindows7の32bitに載せ替えて当初の目標のBUFFALOのDT-H70-U2を快適に動かす方向で行ってみます。

                                           

                                           

                                           

                                           

                                           

                                          2019-1-15 18:01

                                          OSのセットアップ中ではありますが

                                          CPUを調査してあいつにあいそうなやつが

                                          900円で売っていたのでまたポチっとしてしましました。

                                          今度は

                                          こいつです。

                                          Intel Core 2 Duo T7250 2.0GHz 2MB L2 Cache 35W Dual Core CPU SLA49 BX80537T7250

                                          成功すると良いですね。

                                           

                                          2019-1-15 21:00

                                           

                                          OSセットアップとDT-H70-U2のセットアップ完了です。

                                          うまく行きました。成功です。

                                           

                                          OSはWindows7Homeの32Bit版。テレビ専用として来年最終版のアップデート後は

                                          FWを挟んでTV番組の更新だけ行えるように設定して運用すれば良いのかなーと思われます。


                                          Windows10の時はBSやCSはまったく切り替え出来なかったんですけど

                                          今は切り替えバッチリです。(前はハングアップしないけどアプリが固まった)

                                          やっぱ、ハードに合ったOSをインストールするのが一番ですよね。

                                           

                                          いちおう、ポチっとしてしまいましたCPUが届きましたら

                                          乗り掛かった舟なんで、CPU交換までやりますね。

                                           

                                           

                                           

                                           

                                           

                                           

                                           

                                           


                                          ラズパイにSAMBAとSSHでアクセスできるようにする。メモ

                                          0

                                            JUGEMテーマ:電子工作


                                            メモ

                                            ■SAMBA環境構築
                                             sudo apt-get update
                                             sudo apt-get install samba
                                             smbd -V
                                             Version 4.2.14-Debian
                                             
                                             共有名をdataとして設定する
                                             sudo vi /etc/samba/smb.conf
                                             [data]
                                                comment = data
                                                path = /home/pi/picamera/data
                                                guest ok = yes
                                                read only = no
                                                browsable = no
                                                force user = pi

                                            ■SAMBA動作確認
                                             sudo reboot

                                             windowsから確認
                                              エクスプローラーから¥¥192.168.x.x¥dataでアクセス可能

                                            ■SSH環境構築
                                             sudo raspi-config
                                             →Interfaceing Options
                                             →SSH
                                             →はい
                                             →Finish

                                            ■SSH動作確認
                                             TeraTermから192.168.x.xに接続


                                             


                                            画像認識。RaspberryPi3でyolo3実行してみた。

                                            0

                                              RaspberryPi3で画像認識(yolo3)を実行してみた。

                                               

                                              JUGEMテーマ:電子工作

                                               

                                              ■環境構築

                                               

                                              Raspbianの最新版(Raspbian Stretch with desktop and 
                                              recommended software)をダウンロードして32GByteのマイクロSDに焼いて
                                              RaspberryPi3にセットして起動、初期セットアップを完了。

                                              まっさらの状態から以下のコマンドを入れていきます。

                                               

                                              pip3 install matplotlib
                                              sudo apt install libatlas-base-dev
                                              sudo pip3 install opencv-python
                                              sudo pip3 install opencv-contrib-python

                                              sudo apt-get update
                                              sudo apt-get install libhdf5-dev
                                              sudo apt-get update
                                              sudo apt-get install libhdf5-serial-dev

                                              sudo apt-get install libjasper-dev
                                              sudo apt-get install libqt4-test

                                              sudo pip3 install chainer
                                              sudo pip3 install chainercv

                                               

                                              ■LogitecのWebカメラの画像をリアルタイム表示

                                               

                                              ラズパイカメラからのリアルタイム入力できると良いなーと思っておりましたが
                                              cv2.VideoCapture(0)ではラズパイカメラをそのまま認識できない様なので
                                              LogitecのWebカメラから画像を入力します。
                                              パイカメラからの入力はプログラムを修正すれば行けると思うので後日。

                                               

                                              ■Webカメラの画像をリアルタイム表示実行

                                               

                                              python3 Test_Cam.py 0

                                               

                                              ■実行結果

                                               

                                               

                                              19FPSで表示できております。
                                              パソコンでも30FPSぐらいでしたのでラズパイなかなかやるじゃんという感じです。

                                               

                                              ■実行

                                               

                                              python3 yolo3.py 0

                                               

                                              ■実行結果

                                               

                                               

                                              1画像につき55秒かかっております。
                                              さすがにラズパイではキツイか?とも思いますが
                                              ラズパイ用のGPUってあるんでしょうかね?
                                              時々生き物や物体の数を数える程度であればなんとか使えるでしょう。

                                              ちなみに、ラズパイでの実行ではCPU食い過ぎの為なのかもしれませんが
                                              「強制終了」のメッセージとともに中断することがあるようです。

                                               

                                              ■ソース

                                               

                                              ソースは昨日まで作っていたものと同じです。
                                              pythonで作るとWindowsでもラズパイでもそのまま動いて便利ですね。

                                               

                                              ・Test_Cam.py

                                               

                                              import argparse
                                              import cv2
                                              from timeit import default_timer as timer

                                              def main():
                                                  parser = argparse.ArgumentParser()
                                                  parser.add_argument('video')
                                                  args = parser.parse_args()

                                                  if args.video == "0":
                                                      vid = cv2.VideoCapture(0)
                                                  else:
                                                      vid = cv2.VideoCapture(args.video)
                                                  if not vid.isOpened():
                                                      raise ImportError("Couldn't open video file or webcam.")

                                                  # Compute aspect ratio of video
                                                  vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                                                  vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                                                  vidar = vidw / vidh
                                                  print(vidw)
                                                  print(vidh)

                                                  accum_time = 0
                                                  curr_fps = 0
                                                  fps = "FPS: ??"
                                                  prev_time = timer()

                                                  frame_count = 1
                                                  while True:
                                                      ret, frame = vid.read()
                                                      if ret == False:
                                                          print("Done!")
                                                          return

                                                      # Resized
                                                      im_size = (640, 480)
                                                      resized = cv2.resize(frame, im_size)

                                                      # =================================
                                                      # Image Preprocessing
                                                      # =================================

                                                      # =================================
                                                      # Main Processing
                                                      result = resized.copy() # dummy
                                                      # result = frame.copy() # no resize
                                                      # =================================

                                                      # Calculate FPS
                                                      curr_time = timer()
                                                      exec_time = curr_time - prev_time
                                                      prev_time = curr_time
                                                      accum_time = accum_time + exec_time
                                                      curr_fps = curr_fps + 1
                                                      if accum_time > 1:
                                                          accum_time = accum_time - 1
                                                          fps = "FPS:" + str(curr_fps)
                                                          curr_fps = 0

                                                      # Draw FPS in top right corner
                                                      cv2.rectangle(result, (250, 0), (300, 17), (0, 0, 0), -1)
                                                      cv2.putText(result, fps, (255, 10), 
                                                      cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                      # Draw Frame Number
                                                      cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1)
                                                      cv2.putText(result, str(frame_count), (0, 10), 
                                                      cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                      # Output Result
                                                      cv2.imshow("Result", result)

                                                      # Stop Processing
                                                      if cv2.waitKey(1) & 0xFF == ord('q'):
                                                          break

                                                      frame_count += 1

                                              if __name__ == '__main__':
                                                  main()

                                               

                                              ・yolo3.py

                                               

                                              import time
                                              import argparse
                                              import matplotlib.pyplot as plt
                                              import cv2
                                              import numpy as np
                                              from timeit import default_timer as timer
                                              import chainer
                                              from chainercv.datasets import voc_bbox_label_names
                                              from chainercv.datasets import coco_bbox_label_names
                                              from chainercv.links import YOLOv3

                                              #色のテーブル 150まで対応
                                              label_colors = (
                                                  (120, 120, 120),
                                                  (180, 120, 120),
                                                  (6, 230, 230),
                                                  (80, 50, 50),
                                                  (4, 200, 3),
                                                  (120, 120, 80),
                                                  (140, 140, 140),
                                                  (204, 5, 255),
                                                  (230, 230, 230),
                                                  (4, 250, 7),
                                                  (224, 5, 255),
                                                  (235, 255, 7),
                                                  (150, 5, 61),
                                                  (120, 120, 70),
                                                  (8, 255, 51),
                                                  (255, 6, 82),
                                                  (143, 255, 140),
                                                  (204, 255, 4),
                                                  (255, 51, 7),
                                                  (204, 70, 3),
                                                  (0, 102, 200),
                                                  (61, 230, 250),
                                                  (255, 6, 51),
                                                  (11, 102, 255),
                                                  (255, 7, 71),
                                                  (255, 9, 224),
                                                  (9, 7, 230),
                                                  (220, 220, 220),
                                                  (255, 9, 92),
                                                  (112, 9, 255),
                                                  (8, 255, 214),
                                                  (7, 255, 224),
                                                  (255, 184, 6),
                                                  (10, 255, 71),
                                                  (255, 41, 10),
                                                  (7, 255, 255),
                                                  (224, 255, 8),
                                                  (102, 8, 255),
                                                  (255, 61, 6),
                                                  (255, 194, 7),
                                                  (255, 122, 8),
                                                  (0, 255, 20),
                                                  (255, 8, 41),
                                                  (255, 5, 153),
                                                  (6, 51, 255),
                                                  (235, 12, 255),
                                                  (160, 150, 20),
                                                  (0, 163, 255),
                                                  (140, 140, 140),
                                                  (250, 10, 15),
                                                  (20, 255, 0),
                                                  (31, 255, 0),
                                                  (255, 31, 0),
                                                  (255, 224, 0),
                                                  (153, 255, 0),
                                                  (0, 0, 255),
                                                  (255, 71, 0),
                                                  (0, 235, 255),
                                                  (0, 173, 255),
                                                  (31, 0, 255),
                                                  (11, 200, 200),
                                                  (255, 82, 0),
                                                  (0, 255, 245),
                                                  (0, 61, 255),
                                                  (0, 255, 112),
                                                  (0, 255, 133),
                                                  (255, 0, 0),
                                                  (255, 163, 0),
                                                  (255, 102, 0),
                                                  (194, 255, 0),
                                                  (0, 143, 255),
                                                  (51, 255, 0),
                                                  (0, 82, 255),
                                                  (0, 255, 41),
                                                  (0, 255, 173),
                                                  (10, 0, 255),
                                                  (173, 255, 0),
                                                  (0, 255, 153),
                                                  (255, 92, 0),
                                                  (255, 0, 255),
                                                  (255, 0, 245),
                                                  (255, 0, 102),
                                                  (255, 173, 0),
                                                  (255, 0, 20),
                                                  (255, 184, 184),
                                                  (0, 31, 255),
                                                  (0, 255, 61),
                                                  (0, 71, 255),
                                                  (255, 0, 204),
                                                  (0, 255, 194),
                                                  (0, 255, 82),
                                                  (0, 10, 255),
                                                  (0, 112, 255),
                                                  (51, 0, 255),
                                                  (0, 194, 255),
                                                  (0, 122, 255),
                                                  (0, 255, 163),
                                                  (255, 153, 0),
                                                  (0, 255, 10),
                                                  (255, 112, 0),
                                                  (143, 255, 0),
                                                  (82, 0, 255),
                                                  (163, 255, 0),
                                                  (255, 235, 0),
                                                  (8, 184, 170),
                                                  (133, 0, 255),
                                                  (0, 255, 92),
                                                  (184, 0, 255),
                                                  (255, 0, 31),
                                                  (0, 184, 255),
                                                  (0, 214, 255),
                                                  (255, 0, 112),
                                                  (92, 255, 0),
                                                  (0, 224, 255),
                                                  (112, 224, 255),
                                                  (70, 184, 160),
                                                  (163, 0, 255),
                                                  (153, 0, 255),
                                                  (71, 255, 0),
                                                  (255, 0, 163),
                                                  (255, 204, 0),
                                                  (255, 0, 143),
                                                  (0, 255, 235),
                                                  (133, 255, 0),
                                                  (255, 0, 235),
                                                  (245, 0, 255),
                                                  (255, 0, 122),
                                                  (255, 245, 0),
                                                  (10, 190, 212),
                                                  (214, 255, 0),
                                                  (0, 204, 255),
                                                  (20, 0, 255),
                                                  (255, 255, 0),
                                                  (0, 153, 255),
                                                  (0, 41, 255),
                                                  (0, 255, 204),
                                                  (41, 0, 255),
                                                  (41, 255, 0),
                                                  (173, 0, 255),
                                                  (0, 245, 255),
                                                  (71, 0, 255),
                                                  (122, 0, 255),
                                                  (0, 255, 184),
                                                  (0, 92, 255),
                                                  (184, 255, 0),
                                                  (0, 133, 255),
                                                  (255, 214, 0),
                                                  (25, 194, 194),
                                                  (102, 255, 0),
                                                  (92, 0, 255),
                                                  (0, 0, 0)
                                              )

                                              def main():
                                                  parser = argparse.ArgumentParser()
                                                  parser.add_argument('--gpu', type=int, default=-1)
                                                  parser.add_argument('--pretrained-model', default='voc0712')
                                                  parser.add_argument('--class_num', default=20)
                                                  parser.add_argument('--class_list', default=0)
                                                  parser.add_argument('video')
                                                  args = parser.parse_args()

                                                  #
                                                  #パラメータ解析
                                                  # python yolo3.py 0
                                                  #    デフォルトではvoc0712のモデルをダウンロードして来ます。認識できるのは20種類
                                                  #
                                                  # python yolo3.py --pretrained-model yolov3.weights.npz --class_num 80 --class_list yolov3.list 0
                                                  #  --pretrained-model 
                                                  #    darknet2npz.pyで変換した学習済みモデルyolov3.weights.npzを指定
                                                  #  --class_num
                                                  #    上記学習済みモデルのクラス数
                                                  #  --class_list
                                                  #    上記学習済みモデルのクラス名一覧 1行に1クラス
                                                  #  ビデオ
                                                  #    WEBカメラの場合は0
                                                  #    動画ファイルの場合はファイル名
                                                  #
                                                  if args.pretrained_model=='voc0712' :
                                                    label_names = voc_bbox_label_names
                                                    model = YOLOv3(20, 'voc0712')
                                                  else :
                                                    print(args.class_list)
                                                    if args.class_list==0 : 
                                                      label_names = coco_bbox_label_names
                                                    else:
                                                      f = open(args.class_list, "r")
                                                      name_list = []
                                                      for line in f:
                                                        line = line.strip()
                                                        name_list.append(line)
                                                      f.close()
                                                      label_names = name_list
                                                    
                                                    model = YOLOv3(n_fg_class=int(args.class_num), pretrained_model=args.pretrained_model)
                                                  
                                                  #GPU対応
                                                  #  CPUなら省略
                                                  #  GPUなら0
                                                  if args.gpu >= 0:
                                                      chainer.cuda.get_device_from_id(args.gpu).use()
                                                      model.to_gpu()
                                                  #
                                                  #対応しているクラス名一覧を表示する
                                                  #
                                                  for name in label_names:
                                                    print(name)
                                                  #
                                                  #WEBカメラまたは動画ファイルを開く
                                                  #
                                                  if args.video == "0":
                                                      vid = cv2.VideoCapture(0)
                                                  else:
                                                      vid = cv2.VideoCapture(args.video)
                                                  if not vid.isOpened():
                                                      raise ImportError("Couldn't open video file or webcam.")

                                                  
                                                  # Compute aspect ratio of video
                                                  vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                                                  vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                                                  # vidar = vidw / vidh
                                                  print(vidw)
                                                  print(vidh)

                                                  accum_time = 0
                                                  curr_fps = 0
                                                  fps = "FPS: ??"
                                                  prev_time = timer()

                                                  frame_count = 1
                                                  while True:
                                                      ret, frame = vid.read()
                                                      if ret == False:
                                                          time.sleep(5)
                                                          print("Done!")
                                                          return

                                                      # BGR -> RGB
                                                      rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                                                      # Result image
                                                      result = frame.copy()

                                                      # (H, W, C) -> (C, H, W)
                                                      img = np.asarray(rgb, dtype = np.float32).transpose((2, 0, 1))

                                                      # Object Detection
                                                      bboxes, labels, scores = model.predict([img])
                                                      bbox, label, score = bboxes[0], labels[0], scores[0]

                                                      print("----------")
                                                      nPerson = 0
                                                      nBottle = 0
                                                      if len(bbox) != 0:
                                                          for i, bb in enumerate(bbox):
                                                              # print(i)
                                                              lb = label[i]
                                                              conf = score[i].tolist()
                                                              ymin = int(bb[0])
                                                              xmin = int(bb[1])
                                                              ymax = int(bb[2])
                                                              xmax = int(bb[3])

                                                              class_num = int(lb)

                                                              # Draw box 1
                                                              cv2.rectangle(result, (xmin, ymin), (xmax, ymax),
                                                              label_colors[class_num], 2)

                                                              # Draw box 2
                                                              # cv2.rectangle(result, (xmin, ymin), (xmax, ymax), (0,255,0), 2)

                                                              #text = label_names[class_num] + " " + ('%.2f' % conf)
                                                              text = label_names[class_num] + " " + ('%.2f' % conf)
                                                              print(text)
                                                              if(label_names[class_num] == 'person'):
                                                                nPerson = nPerson + 1
                                                              if(label_names[class_num] == 'bottle'):
                                                                nBottle = nBottle + 1
                                                              
                                                              text_top = (xmin, ymin - 10)
                                                              text_bot = (xmin + 80, ymin + 5)
                                                              text_pos = (xmin + 5, ymin)

                                                              # Draw label 1
                                                              cv2.rectangle(result, text_top, text_bot, 
                                                              label_colors[class_num], -1)
                                                              cv2.putText(result, text, text_pos, 
                                                              cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)

                                                              # Draw label 2
                                                              # cv2.rectangle(result, text_top, text_bot, (255,255,255), -1)
                                                              # cv2.putText(result, text, text_pos, 
                                                              # cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)
                                                          print("==========")
                                                          print("Number of people : " + str(nPerson))
                                                          print("Number of bottle : " + str(nBottle))
                                                      # Calculate FPS
                                                      curr_time = timer()
                                                      exec_time = curr_time - prev_time
                                                      prev_time = curr_time
                                                      accum_time = accum_time + exec_time
                                                      curr_fps = curr_fps + 1
                                                      if accum_time > 1:
                                                          accum_time = accum_time - 1
                                                          fps = "FPS:" + str(curr_fps)
                                                          curr_fps = 0

                                                      # Draw FPS in top right corner
                                                      cv2.rectangle(result, (590, 0), (640, 17), (0, 0, 0), -1)
                                                      cv2.putText(result, fps, (595, 10), 
                                                      cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                      # Draw Frame Number
                                                      cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1)
                                                      cv2.putText(result, str(frame_count), (0, 10), 
                                                      cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                      # Output Result
                                                      cv2.imshow("Yolo Result", result)

                                                      # Stop Processing
                                                      if cv2.waitKey(1) & 0xFF == ord('q'):
                                                          break

                                                      frame_count += 1

                                              if __name__ == '__main__':
                                                  main()
                                                  


                                               


                                              学習済みファイルの作成とクラス名について(chainerを使った場合のyolo3の研究)

                                              0

                                                学習済みファイルの作成とクラス名について(chainerを使った場合のyoloの研究)

                                                 

                                                JUGEMテーマ:電子工作

                                                 

                                                ■yoloの学習済みモデルのファイルの場所

                                                 C:¥Users¥user¥.chainer¥dataset¥pfnet¥chainercv¥models
                                                  yolo_v2_voc0712_converted_2018_05_03.npz
                                                  yolo_v3_voc0712_converted_2018_05_01.npz

                                                 

                                                ■学習済みモデルのファイルの指定
                                                 ソース中の
                                                    model = YOLOv3(
                                                      n_fg_class=len(voc_bbox_label_names),
                                                      pretrained_model=args.pretrained_model)
                                                  の所で
                                                    model = YOLOv3(
                                                      n_fg_class=20,
                                                      pretrained_model='C:¥¥Users¥¥user¥¥.chainer¥¥dataset¥¥pfnet¥¥chainercv¥¥models¥¥x.npz')
                                                  等とすればファイルを指定可能。拡張子はnpz
                                                  ファイルを指定する場合はn_fg_classを正しく指定する必要がある
                                                  
                                                ■学習済みファイルの作成
                                                 darknetで作成した学習済みモデルをnpzファイルに変換する必要がある。
                                                 変換コードはchainercv/examples/yolo/darknet2npz.py
                                                 デフォルトでは入っていないので以下からダウンロード
                                                 https://github.com/chainer/chainercv/blob/master/examples/yolo/darknet2npz.py
                                                 yolo_v2_tinyとYOLOv2Tinyの記述のある行はエラーになるのでコメントアウト
                                                 
                                                 ダークネット学習済みモデルファイルは以下からダウンロード
                                                 https://pjreddie.com/media/files/yolov3.weights
                                                 80クラスに対応している模様です。
                                                 
                                                 変換実行
                                                  python darknet2npz.py --model yolo_v3 --n-fg-class 80 yolov3.weights yolov3.weights.npz

                                                 

                                                ■変換した学習済みファイルを使ったyolo3対応画像認識プログラム

                                                 起動方法
                                                  python yolo3.py --pretrained-model yolov3.weights.npz --class_num 80 --class_list yolov3.list 0
                                                  上記で作成した学習済みモデルファイル(yolov3.weights.npz)と

                                                  それに対応したクラス名ファイル(yolov3.list)が必要です。
                                                  --pretrained-model 
                                                   上記darknet2npz.pyで変換した学習済みモデルyolov3.weights.npzを指定
                                                  --class_num
                                                   上記学習済みモデルのクラス数(上記のyolov3.weights.npzは80)
                                                  --class_list
                                                   上記学習済みモデルのクラス名一覧 1行に1クラス(下記)
                                                  --gpu
                                                   gpuなら0
                                                   cpuなら省略
                                                  ビデオ
                                                   WEBカメラの場合は0
                                                   動画ファイルの場合はファイル名

                                                 

                                                ■クラス名ファイル(yolov3.list)

                                                 

                                                ・yolov3.list

                                                 

                                                person
                                                bicycle
                                                car
                                                motorcycle
                                                airplane
                                                bus
                                                train
                                                truck
                                                boat
                                                traffic light
                                                fire hydrant
                                                stop sign
                                                parking meter
                                                bench
                                                bird
                                                cat
                                                dog
                                                horse
                                                sheep
                                                cow
                                                elephant
                                                bear
                                                zebra
                                                giraffe
                                                backpack
                                                umbrella
                                                handbag
                                                tie
                                                suitcase
                                                frisbee
                                                skis
                                                snowboard
                                                sports ball
                                                kite
                                                baseball bat
                                                baseball glove
                                                skateboard
                                                surfboard
                                                tennis racket
                                                bottle
                                                wine glass
                                                cup
                                                fork
                                                knife
                                                spoon
                                                bowl
                                                banana
                                                apple
                                                sandwich
                                                orange
                                                broccoli
                                                carrot
                                                hot dog
                                                pizza
                                                donut
                                                cake
                                                chair
                                                couch
                                                potted plant
                                                bed
                                                dining table
                                                toilet
                                                tv
                                                laptop
                                                mouse
                                                remote
                                                keyboard
                                                cell phone
                                                microwave
                                                oven
                                                toaster
                                                sink
                                                refrigerator
                                                book
                                                clock
                                                vase
                                                scissors
                                                teddy bear
                                                hair drier
                                                toothbrush

                                                 

                                                ■ソース

                                                 

                                                ・yolo3.py

                                                 

                                                import time
                                                import argparse
                                                import matplotlib.pyplot as plt
                                                import cv2
                                                import numpy as np
                                                from timeit import default_timer as timer
                                                import chainer
                                                from chainercv.datasets import voc_bbox_label_names
                                                from chainercv.datasets import coco_bbox_label_names
                                                from chainercv.links import YOLOv3

                                                #色のテーブル 150まで対応
                                                label_colors = (
                                                    (120, 120, 120),
                                                    (180, 120, 120),
                                                    (6, 230, 230),
                                                    (80, 50, 50),
                                                    (4, 200, 3),
                                                    (120, 120, 80),
                                                    (140, 140, 140),
                                                    (204, 5, 255),
                                                    (230, 230, 230),
                                                    (4, 250, 7),
                                                    (224, 5, 255),
                                                    (235, 255, 7),
                                                    (150, 5, 61),
                                                    (120, 120, 70),
                                                    (8, 255, 51),
                                                    (255, 6, 82),
                                                    (143, 255, 140),
                                                    (204, 255, 4),
                                                    (255, 51, 7),
                                                    (204, 70, 3),
                                                    (0, 102, 200),
                                                    (61, 230, 250),
                                                    (255, 6, 51),
                                                    (11, 102, 255),
                                                    (255, 7, 71),
                                                    (255, 9, 224),
                                                    (9, 7, 230),
                                                    (220, 220, 220),
                                                    (255, 9, 92),
                                                    (112, 9, 255),
                                                    (8, 255, 214),
                                                    (7, 255, 224),
                                                    (255, 184, 6),
                                                    (10, 255, 71),
                                                    (255, 41, 10),
                                                    (7, 255, 255),
                                                    (224, 255, 8),
                                                    (102, 8, 255),
                                                    (255, 61, 6),
                                                    (255, 194, 7),
                                                    (255, 122, 8),
                                                    (0, 255, 20),
                                                    (255, 8, 41),
                                                    (255, 5, 153),
                                                    (6, 51, 255),
                                                    (235, 12, 255),
                                                    (160, 150, 20),
                                                    (0, 163, 255),
                                                    (140, 140, 140),
                                                    (250, 10, 15),
                                                    (20, 255, 0),
                                                    (31, 255, 0),
                                                    (255, 31, 0),
                                                    (255, 224, 0),
                                                    (153, 255, 0),
                                                    (0, 0, 255),
                                                    (255, 71, 0),
                                                    (0, 235, 255),
                                                    (0, 173, 255),
                                                    (31, 0, 255),
                                                    (11, 200, 200),
                                                    (255, 82, 0),
                                                    (0, 255, 245),
                                                    (0, 61, 255),
                                                    (0, 255, 112),
                                                    (0, 255, 133),
                                                    (255, 0, 0),
                                                    (255, 163, 0),
                                                    (255, 102, 0),
                                                    (194, 255, 0),
                                                    (0, 143, 255),
                                                    (51, 255, 0),
                                                    (0, 82, 255),
                                                    (0, 255, 41),
                                                    (0, 255, 173),
                                                    (10, 0, 255),
                                                    (173, 255, 0),
                                                    (0, 255, 153),
                                                    (255, 92, 0),
                                                    (255, 0, 255),
                                                    (255, 0, 245),
                                                    (255, 0, 102),
                                                    (255, 173, 0),
                                                    (255, 0, 20),
                                                    (255, 184, 184),
                                                    (0, 31, 255),
                                                    (0, 255, 61),
                                                    (0, 71, 255),
                                                    (255, 0, 204),
                                                    (0, 255, 194),
                                                    (0, 255, 82),
                                                    (0, 10, 255),
                                                    (0, 112, 255),
                                                    (51, 0, 255),
                                                    (0, 194, 255),
                                                    (0, 122, 255),
                                                    (0, 255, 163),
                                                    (255, 153, 0),
                                                    (0, 255, 10),
                                                    (255, 112, 0),
                                                    (143, 255, 0),
                                                    (82, 0, 255),
                                                    (163, 255, 0),
                                                    (255, 235, 0),
                                                    (8, 184, 170),
                                                    (133, 0, 255),
                                                    (0, 255, 92),
                                                    (184, 0, 255),
                                                    (255, 0, 31),
                                                    (0, 184, 255),
                                                    (0, 214, 255),
                                                    (255, 0, 112),
                                                    (92, 255, 0),
                                                    (0, 224, 255),
                                                    (112, 224, 255),
                                                    (70, 184, 160),
                                                    (163, 0, 255),
                                                    (153, 0, 255),
                                                    (71, 255, 0),
                                                    (255, 0, 163),
                                                    (255, 204, 0),
                                                    (255, 0, 143),
                                                    (0, 255, 235),
                                                    (133, 255, 0),
                                                    (255, 0, 235),
                                                    (245, 0, 255),
                                                    (255, 0, 122),
                                                    (255, 245, 0),
                                                    (10, 190, 212),
                                                    (214, 255, 0),
                                                    (0, 204, 255),
                                                    (20, 0, 255),
                                                    (255, 255, 0),
                                                    (0, 153, 255),
                                                    (0, 41, 255),
                                                    (0, 255, 204),
                                                    (41, 0, 255),
                                                    (41, 255, 0),
                                                    (173, 0, 255),
                                                    (0, 245, 255),
                                                    (71, 0, 255),
                                                    (122, 0, 255),
                                                    (0, 255, 184),
                                                    (0, 92, 255),
                                                    (184, 255, 0),
                                                    (0, 133, 255),
                                                    (255, 214, 0),
                                                    (25, 194, 194),
                                                    (102, 255, 0),
                                                    (92, 0, 255),
                                                    (0, 0, 0)
                                                )

                                                def main():
                                                    parser = argparse.ArgumentParser()
                                                    parser.add_argument('--gpu', type=int, default=-1)
                                                    parser.add_argument('--pretrained-model', default='voc0712')
                                                    parser.add_argument('--class_num', default=20)
                                                    parser.add_argument('--class_list', default=0)
                                                    parser.add_argument('video')
                                                    args = parser.parse_args()

                                                    #
                                                    #パラメータ解析
                                                    # python yolo3.py 0
                                                    #    デフォルトではvoc0712のモデルをダウンロードして来ます。認識できるのは20種類
                                                    #
                                                    # python yolo3.py --pretrained-model yolov3.weights.npz --class_num 80 --class_list yolov3.list 0
                                                    #  --pretrained-model 
                                                    #    darknet2npz.pyで変換した学習済みモデルyolov3.weights.npzを指定
                                                    #  --class_num
                                                    #    上記学習済みモデルのクラス数
                                                    #  --class_list
                                                    #    上記学習済みモデルのクラス名一覧 1行に1クラス
                                                    #  ビデオ
                                                    #    WEBカメラの場合は0
                                                    #    動画ファイルの場合はファイル名
                                                    #
                                                    if args.pretrained_model=='voc0712' :
                                                      label_names = voc_bbox_label_names
                                                      model = YOLOv3(20, 'voc0712')
                                                    else :
                                                      print(args.class_list)
                                                      if args.class_list==0 : 
                                                        label_names = coco_bbox_label_names
                                                      else:
                                                        f = open(args.class_list, "r")
                                                        name_list = []
                                                        for line in f:
                                                          line = line.strip()
                                                          name_list.append(line)
                                                        f.close()
                                                        label_names = name_list
                                                      
                                                      model = YOLOv3(n_fg_class=int(args.class_num), pretrained_model=args.pretrained_model)
                                                    
                                                    #GPU対応
                                                    #  CPUなら省略
                                                    #  GPUなら0
                                                    if args.gpu >= 0:
                                                        chainer.cuda.get_device_from_id(args.gpu).use()
                                                        model.to_gpu()
                                                    #
                                                    #対応しているクラス名一覧を表示する
                                                    #
                                                    for name in label_names:
                                                      print(name)
                                                    #
                                                    #WEBカメラまたは動画ファイルを開く
                                                    #
                                                    if args.video == "0":
                                                        vid = cv2.VideoCapture(0)
                                                    else:
                                                        vid = cv2.VideoCapture(args.video)
                                                    if not vid.isOpened():
                                                        raise ImportError("Couldn't open video file or webcam.")

                                                    
                                                    # Compute aspect ratio of video
                                                    vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                                                    vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                                                    # vidar = vidw / vidh
                                                    print(vidw)
                                                    print(vidh)

                                                    accum_time = 0
                                                    curr_fps = 0
                                                    fps = "FPS: ??"
                                                    prev_time = timer()

                                                    frame_count = 1
                                                    while True:
                                                        ret, frame = vid.read()
                                                        if ret == False:
                                                            time.sleep(5)
                                                            print("Done!")
                                                            return

                                                        # BGR -> RGB
                                                        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                                                        # Result image
                                                        result = frame.copy()

                                                        # (H, W, C) -> (C, H, W)
                                                        img = np.asarray(rgb, dtype = np.float32).transpose((2, 0, 1))

                                                        # Object Detection
                                                        bboxes, labels, scores = model.predict([img])
                                                        bbox, label, score = bboxes[0], labels[0], scores[0]

                                                        print("----------")
                                                        nPerson = 0
                                                        nBottle = 0
                                                        if len(bbox) != 0:
                                                            for i, bb in enumerate(bbox):
                                                                # print(i)
                                                                lb = label[i]
                                                                conf = score[i].tolist()
                                                                ymin = int(bb[0])
                                                                xmin = int(bb[1])
                                                                ymax = int(bb[2])
                                                                xmax = int(bb[3])

                                                                class_num = int(lb)

                                                                # Draw box 1
                                                                cv2.rectangle(result, (xmin, ymin), (xmax, ymax),
                                                                label_colors[class_num], 2)

                                                                # Draw box 2
                                                                # cv2.rectangle(result, (xmin, ymin), (xmax, ymax), (0,255,0), 2)

                                                                #text = label_names[class_num] + " " + ('%.2f' % conf)
                                                                text = label_names[class_num] + " " + ('%.2f' % conf)
                                                                print(text)
                                                                if(label_names[class_num] == 'person'):
                                                                  nPerson = nPerson + 1
                                                                if(label_names[class_num] == 'bottle'):
                                                                  nBottle = nBottle + 1
                                                                
                                                                text_top = (xmin, ymin - 10)
                                                                text_bot = (xmin + 80, ymin + 5)
                                                                text_pos = (xmin + 5, ymin)

                                                                # Draw label 1
                                                                cv2.rectangle(result, text_top, text_bot, 
                                                                label_colors[class_num], -1)
                                                                cv2.putText(result, text, text_pos, 
                                                                cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)

                                                                # Draw label 2
                                                                # cv2.rectangle(result, text_top, text_bot, (255,255,255), -1)
                                                                # cv2.putText(result, text, text_pos, 
                                                                # cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)
                                                            print("==========")
                                                            print("Number of people : " + str(nPerson))
                                                            print("Number of bottle : " + str(nBottle))
                                                        # Calculate FPS
                                                        curr_time = timer()
                                                        exec_time = curr_time - prev_time
                                                        prev_time = curr_time
                                                        accum_time = accum_time + exec_time
                                                        curr_fps = curr_fps + 1
                                                        if accum_time > 1:
                                                            accum_time = accum_time - 1
                                                            fps = "FPS:" + str(curr_fps)
                                                            curr_fps = 0

                                                        # Draw FPS in top right corner
                                                        cv2.rectangle(result, (590, 0), (640, 17), (0, 0, 0), -1)
                                                        cv2.putText(result, fps, (595, 10), 
                                                        cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                        # Draw Frame Number
                                                        cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1)
                                                        cv2.putText(result, str(frame_count), (0, 10), 
                                                        cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                        # Output Result
                                                        cv2.imshow("Yolo Result", result)

                                                        # Stop Processing
                                                        if cv2.waitKey(1) & 0xFF == ord('q'):
                                                            break

                                                        frame_count += 1

                                                if __name__ == '__main__':
                                                    main()
                                                    

                                                ・darknet2npz.py

                                                 

                                                import argparse
                                                import numpy as np

                                                import chainer
                                                from chainer.links import Convolution2D
                                                from chainer import serializers

                                                #from chainercv.experimental.links import YOLOv2Tiny
                                                from chainercv.links import Conv2DBNActiv
                                                from chainercv.links import YOLOv2
                                                from chainercv.links import YOLOv3


                                                def load_param(file, param):
                                                    if isinstance(param, chainer.Variable):
                                                        param = param.array
                                                    param[:] = np.fromfile(file, dtype=np.float32, count=param.size) ¥
                                                                 .reshape(param.shape)


                                                def load_link(file, link):
                                                    if isinstance(link, Convolution2D):
                                                        load_param(file, link.b)
                                                        load_param(file, link.W)
                                                    elif isinstance(link, Conv2DBNActiv):
                                                        load_param(file, link.bn.beta)
                                                        load_param(file, link.bn.gamma)
                                                        load_param(file, link.bn.avg_mean)
                                                        load_param(file, link.bn.avg_var)
                                                        load_param(file, link.conv.W)
                                                    elif isinstance(link, chainer.ChainList):
                                                        for l in link:
                                                            load_link(file, l)


                                                def reorder_loc(conv, n_fg_class):
                                                    # xy -> yx
                                                    for data in (conv.W.array, conv.b.array):
                                                        data = data.reshape(
                                                            (-1, 4 + 1 + n_fg_class) + data.shape[1:])
                                                        data[:, [1, 0, 3, 2]] = data[:, :4].copy()


                                                def load_yolo_v2(file, model):
                                                    load_link(file, model.extractor)
                                                    load_link(file, model.subnet)

                                                    reorder_loc(model.subnet, model.n_fg_class)


                                                def load_yolo_v3(file, model):
                                                    for i, link in enumerate(model.extractor):
                                                        load_link(file, link)
                                                        if i in {33, 39, 45}:
                                                            subnet = model.subnet[(i - 33) // 6]
                                                            load_link(file, subnet)

                                                    for subnet in model.subnet:
                                                        reorder_loc(subnet[-1], model.n_fg_class)


                                                def main():
                                                    parser = argparse.ArgumentParser()
                                                    parser.add_argument(
                                                        '--model', choices=('yolo_v2', 'yolo_v2_tiny', 'yolo_v3'),
                                                        default='yolo_v2')
                                                    parser.add_argument('--n-fg-class', type=int, default=80)
                                                    parser.add_argument('darknetmodel')
                                                    parser.add_argument('output')
                                                    args = parser.parse_args()

                                                    if args.model == 'yolo_v2':
                                                        model = YOLOv2(n_fg_class=args.n_fg_class)
                                                    #elif args.model == 'yolo_v2_tiny':
                                                    #    model = YOLOv2Tiny(n_fg_class=args.n_fg_class)
                                                    elif args.model == 'yolo_v3':
                                                        model = YOLOv3(n_fg_class=args.n_fg_class)

                                                    with chainer.using_config('train', False):
                                                        model(np.empty((1, 3, model.insize, model.insize), dtype=np.float32))

                                                    with open(args.darknetmodel, mode='rb') as f:
                                                        major = np.fromfile(f, dtype=np.int32, count=1)
                                                        minor = np.fromfile(f, dtype=np.int32, count=1)
                                                        np.fromfile(f, dtype=np.int32, count=1)  # revision
                                                        if major * 10 + minor >= 2 and major < 1000 and minor < 1000:
                                                            np.fromfile(f, dtype=np.int64, count=1)  # seen
                                                        else:
                                                            np.fromfile(f, dtype=np.int32, count=1)  # seen

                                                        if args.model == 'yolo_v2':
                                                            load_yolo_v2(f, model)
                                                        elif args.model == 'yolo_v2_tiny':
                                                            load_yolo_v2(f, model)
                                                        elif args.model == 'yolo_v3':
                                                            load_yolo_v3(f, model)

                                                    serializers.save_npz(args.output, model)


                                                if __name__ == '__main__':
                                                    main()
                                                 

                                                 


                                                画像認識して画像に映っている物体の数をリアルタイムに数える

                                                0

                                                  JUGEMテーマ:趣味

                                                  JUGEMテーマ:電子工作

                                                  画像認識して画像に映っている物体の数をリアルタイムに数える

                                                   

                                                  Webカメラの画像からリアルタイムにその場にいる人の数を数えるとか、
                                                  熊を検出するとか、鹿を検出するとかそう言った事が最近は出来るらしいです。

                                                  かなり進歩したもんですね。

                                                  技術的な要素としてはyoloとかOpenCVとかを使うと良いとの事で、
                                                  色々な所にハマりながらたどり着いたのがこちら。

                                                  https://cpp-learning.com/chainercv_yolo/
                                                  とっても素敵なページです。こういった事を惜しげもなく公開しているオーナーさんには感謝です。
                                                  今ページの記事は基本的に上記ページの再現になります。

                                                  上記ページによりますと、chainerからyoloが使用可能で、以下の機能分担になります。
                                                   openCV : ビデオ入力
                                                   ChainerCV : yoloを使用して画像認識
                                                   openCV : 結果を画面出力

                                                  以下、環境構築から実際に物体を認識するまでの記録(自分用メモ)として残したいと思います。

                                                   

                                                  ■chainerの環境構築
                                                  ※参考サイト
                                                   https://cpp-learning.com/anaconda_windows_chainer/
                                                  手順は以下の通り
                                                   ・Anacondaインストール
                                                   ・Visual C++ Build Toolsインストール
                                                   ・Chainerインストール
                                                   ※「Visual C++ Build Tools」についてはChainerをインストールするのに必要との事。

                                                  ・Anacondaインストール
                                                   ダウンロード
                                                    https://www.anaconda.com/download/#windows
                                                    ここから WindowsのPython3.7のをダウンロードして
                                                    画面の指示に従ってデフォルトでインストールする。

                                                  ・Visual C++ Build Toolsインストール
                                                   ダウンロード
                                                    https://www.visualstudio.com/ja/downloads
                                                    ここの下のほうから「Tools for Visual Studio 2017」をダウンロードして
                                                    画面の指示に従ってデフォルトでインストールする。

                                                  ・Chainerインストール
                                                   anacondaの仮想環境を一つ追加してそこにChainerをインストールしていきます。
                                                   スタートメニューからAnaconda→「anaconda prompt」を起動して以下のコマンドを投入していきます。
                                                   conda create -n chainer Anaconda
                                                   activate chainer
                                                   pip install chainer
                                                   pip install chainercv
                                                   pip install opencv-python
                                                   
                                                  ■カメラ画像を画面にリアルタイム表示
                                                  ここでは画像の解析の前にカメラでから入力した画像をほぼそのまま画面に表示するプログラムになります。
                                                  WindowsなのでLogicoolのWEBカメラをUSB接続してそのまま画面出力するサンプルです。
                                                  画面の上部に現在のフレーム数とFPSを表示していますが、私に環境では30FPSで処理できているようです。
                                                  ※参考サイト
                                                   https://cpp-learning.com/python_opencv_video/
                                                  ・ソース そのままパクっております。自分メモのため・・・汗;;;

                                                   

                                                  Test_Cam.py

                                                   

                                                  import argparse
                                                  import cv2
                                                  from timeit import default_timer as timer

                                                  def main():
                                                      parser = argparse.ArgumentParser()
                                                      parser.add_argument('video')
                                                      args = parser.parse_args()

                                                      if args.video == "0":
                                                          vid = cv2.VideoCapture(0)
                                                      else:
                                                          vid = cv2.VideoCapture(args.video)
                                                      if not vid.isOpened():
                                                          raise ImportError("Couldn't open video file or webcam.")

                                                      # Compute aspect ratio of video
                                                      vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                                                      vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                                                      vidar = vidw / vidh
                                                      print(vidw)
                                                      print(vidh)

                                                      accum_time = 0
                                                      curr_fps = 0
                                                      fps = "FPS: ??"
                                                      prev_time = timer()

                                                      frame_count = 1
                                                      while True:
                                                          ret, frame = vid.read()
                                                          if ret == False:
                                                              print("Done!")
                                                              return

                                                          # Resized
                                                          im_size = (300, 300)
                                                          resized = cv2.resize(frame, im_size)

                                                          # =================================
                                                          # Image Preprocessing
                                                          # =================================

                                                          # =================================
                                                          # Main Processing
                                                          result = resized.copy() # dummy
                                                          # result = frame.copy() # no resize
                                                          # =================================

                                                          # Calculate FPS
                                                          curr_time = timer()
                                                          exec_time = curr_time - prev_time
                                                          prev_time = curr_time
                                                          accum_time = accum_time + exec_time
                                                          curr_fps = curr_fps + 1
                                                          if accum_time > 1:
                                                              accum_time = accum_time - 1
                                                              fps = "FPS:" + str(curr_fps)
                                                              curr_fps = 0

                                                          # Draw FPS in top right corner
                                                          cv2.rectangle(result, (250, 0), (300, 17), (0, 0, 0), -1)
                                                          cv2.putText(result, fps, (255, 10), 
                                                          cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                          # Draw Frame Number
                                                          cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1)
                                                          cv2.putText(result, str(frame_count), (0, 10), 
                                                          cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                          # Output Result
                                                          cv2.imshow("Result", result)

                                                          # Stop Processing
                                                          if cv2.waitKey(1) & 0xFF == ord('q'):
                                                              break

                                                          frame_count += 1

                                                  if __name__ == '__main__':
                                                      main()

                                                   

                                                  ■カメラ画像表示の動作確認
                                                  動作確認
                                                   WEBカメラからの画像の場合はパラメーターに0を指定
                                                    python Test_Cam.py 0
                                                   動画ファイルを指定する場合はパラメーターに動画ファイル名を指定
                                                    python Test_Cam.py 動画ファイル名

                                                   

                                                   

                                                  ■画像認識

                                                  後からわかったんですがyoloのVersion3の場合で最初から学習済みの物体は以下の20種類の様です。
                                                  つまりこれ以外はちゃんと認識されません。
                                                   aeroplane
                                                   bicycle
                                                   bird
                                                   boat
                                                   bottle
                                                   bus
                                                   car
                                                   cat
                                                   chair
                                                   cow
                                                   diningtable
                                                   dog
                                                   horse
                                                   motorbike
                                                   person
                                                   pottedplant
                                                   sheep
                                                   sofa
                                                   train
                                                   tvmonitor
                                                  とりあえずは人を認識できれば今のところはそれで良いかなーとは思います。
                                                  もっと認識を増やしたい場合は学習させればよいという事ですよね。

                                                   

                                                  ■ソース
                                                  ※参考サイト
                                                   https://cpp-learning.com/chainercv_yolo/
                                                  ・ソース ほぼそのままパクっております。自分メモのため・・・汗;;;

                                                   

                                                  Yolo_Chainer_Video.py

                                                   

                                                  import time
                                                  import argparse
                                                  import matplotlib.pyplot as plt
                                                  import cv2
                                                  import numpy as np
                                                  from timeit import default_timer as timer
                                                  import chainer
                                                  from chainercv.datasets import voc_bbox_label_names, voc_semantic_segmentation_label_colors
                                                  from chainercv.links import YOLOv2
                                                  from chainercv.links import YOLOv3
                                                  from chainercv import utils
                                                  from chainercv.visualizations import vis_bbox

                                                  def main():
                                                      parser = argparse.ArgumentParser()
                                                      parser.add_argument(
                                                          '--model', choices=('yolo_v2', 'yolo_v3'),
                                                          default='yolo_v3')
                                                      parser.add_argument('--gpu', type=int, default=-1)
                                                      parser.add_argument('--pretrained-model', default='voc0712')
                                                      parser.add_argument('video')
                                                      args = parser.parse_args()

                                                      if args.model == 'yolo_v2':
                                                          model = YOLOv2(
                                                              n_fg_class=len(voc_bbox_label_names),
                                                              pretrained_model=args.pretrained_model)
                                                      elif args.model == 'yolo_v3':
                                                          model = YOLOv3(
                                                              n_fg_class=len(voc_bbox_label_names),
                                                              pretrained_model=args.pretrained_model)

                                                      for name in voc_bbox_label_names:
                                                        print(name)

                                                      if args.gpu >= 0:
                                                          chainer.cuda.get_device_from_id(args.gpu).use()
                                                          model.to_gpu()

                                                      if args.video == "0":
                                                          vid = cv2.VideoCapture(0)
                                                      else:
                                                          vid = cv2.VideoCapture(args.video)
                                                      if not vid.isOpened():
                                                          raise ImportError("Couldn't open video file or webcam.")

                                                      # Compute aspect ratio of video
                                                      vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
                                                      vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
                                                      # vidar = vidw / vidh
                                                      print(vidw)
                                                      print(vidh)

                                                      accum_time = 0
                                                      curr_fps = 0
                                                      fps = "FPS: ??"
                                                      prev_time = timer()

                                                      frame_count = 1
                                                      while True:
                                                          ret, frame = vid.read()
                                                          if ret == False:
                                                              time.sleep(5)
                                                              print("Done!")
                                                              return

                                                          # BGR -> RGB
                                                          rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                                                          # Result image
                                                          result = frame.copy()

                                                          # (H, W, C) -> (C, H, W)
                                                          img = np.asarray(rgb, dtype = np.float32).transpose((2, 0, 1))

                                                          # Object Detection
                                                          bboxes, labels, scores = model.predict([img])
                                                          bbox, label, score = bboxes[0], labels[0], scores[0]

                                                          print("----------")
                                                          nPerson = 0
                                                          nBottle = 0
                                                          if len(bbox) != 0:
                                                              for i, bb in enumerate(bbox):
                                                                  # print(i)
                                                                  lb = label[i]
                                                                  conf = score[i].tolist()
                                                                  ymin = int(bb[0])
                                                                  xmin = int(bb[1])
                                                                  ymax = int(bb[2])
                                                                  xmax = int(bb[3])

                                                                  class_num = int(lb)

                                                                  # Draw box 1
                                                                  cv2.rectangle(result, (xmin, ymin), (xmax, ymax),
                                                                  voc_semantic_segmentation_label_colors[class_num], 2)

                                                                  # Draw box 2
                                                                  # cv2.rectangle(result, (xmin, ymin), (xmax, ymax), (0,255,0), 2)

                                                                  text = voc_bbox_label_names[class_num] + " " + ('%.2f' % conf)
                                                                  print(text)
                                                                  if(voc_bbox_label_names[class_num] == 'person'):
                                                                    nPerson = nPerson + 1
                                                                  if(voc_bbox_label_names[class_num] == 'bottle'):
                                                                    nBottle = nBottle + 1
                                                                  
                                                                  text_top = (xmin, ymin - 10)
                                                                  text_bot = (xmin + 80, ymin + 5)
                                                                  text_pos = (xmin + 5, ymin)

                                                                  # Draw label 1
                                                                  cv2.rectangle(result, text_top, text_bot, 
                                                                  voc_semantic_segmentation_label_colors[class_num], -1)
                                                                  cv2.putText(result, text, text_pos, 
                                                                  cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)

                                                                  # Draw label 2
                                                                  # cv2.rectangle(result, text_top, text_bot, (255,255,255), -1)
                                                                  # cv2.putText(result, text, text_pos, 
                                                                  # cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)
                                                              print("==========")
                                                              print("Number of people : " + str(nPerson))
                                                              print("Number of bottle : " + str(nBottle))
                                                          # Calculate FPS
                                                          curr_time = timer()
                                                          exec_time = curr_time - prev_time
                                                          prev_time = curr_time
                                                          accum_time = accum_time + exec_time
                                                          curr_fps = curr_fps + 1
                                                          if accum_time > 1:
                                                              accum_time = accum_time - 1
                                                              fps = "FPS:" + str(curr_fps)
                                                              curr_fps = 0

                                                          # Draw FPS in top right corner
                                                          cv2.rectangle(result, (590, 0), (640, 17), (0, 0, 0), -1)
                                                          cv2.putText(result, fps, (595, 10), 
                                                          cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                          # Draw Frame Number
                                                          cv2.rectangle(result, (0, 0), (50, 17), (0, 0, 0), -1)
                                                          cv2.putText(result, str(frame_count), (0, 10), 
                                                          cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

                                                          # Output Result
                                                          cv2.imshow("Yolo Result", result)

                                                          # Stop Processing
                                                          if cv2.waitKey(1) & 0xFF == ord('q'):
                                                              break

                                                          frame_count += 1

                                                  if __name__ == '__main__':
                                                      main()

                                                   

                                                  ■解説
                                                   ・OpenCVでカメラ画像を取得→frame
                                                   ・frameの中身はBGRで入っているそうなので、Chainerで扱えるRGBに変換→rgb
                                                   ・画像サイズとチャンネルの順番がOpenCV(H, W, C)とChainer(C, H, W)で異なる事と
                                                    Chainerではnumpy配列のfloat32しか扱えないのでChainerで扱えるように変換→img
                                                   ・結果出力ではOpenCVを使うのでframeをコピーしておく→result
                                                   ・imgに対し物体検出(Yolo)を実施し、boxとlabelの算出結果を取得
                                                   ・boxとlabelの結果をresultに描画して映像出力

                                                   

                                                  ■画像認識動作確認
                                                  動作確認
                                                   WEBカメラからの画像の場合はパラメーターに0を指定
                                                    python Yolo_Chainer_Video.py 0
                                                   動画ファイルを指定する場合はパラメーターに動画ファイル名を指定
                                                    python Yolo_Chainer_Video.py 動画ファイル名
                                                   より細かい指定をしたい場合はyoloのバージョン、GPU指定、学習モデルなどの指定が可能
                                                    python Yolo_Chainer_Video.py --model yolo_v3 --gpu 0 --pretrained-model voc0712 0
                                                     --model  yoloのバージョン指定  YoloV3 または YoloV2
                                                     --gpu  プロセッサ設定  CPUなら-1 GPUなら0
                                                     --pretrained-model 学習モデル指定  voc0712など
                                                     最後の数字 WEBカメラは0、動画ならファイル名

                                                   

                                                  ・性能について
                                                   私の環境はCPU:Codei5-8400、2.8GHz RAM:32GByte、gpu無しなのですが
                                                   1FPSの速度です。CPU使用率は100%に張り付きます。


                                                  ・認識精度について
                                                   私の手はcatとかdogとか間違われてしまったりしましたが、
                                                   全体であれば私をpersonと認識してくれました。むしろ部分でもpersonなのね。という感じです。
                                                   牛とか車とか学習済みのものは正確に認識してくれます。
                                                   熊の写真とかであれば同じ動物の仲間のdogとかcow等と認識しておりまずまずの結果かと思います。

                                                   

                                                   

                                                   

                                                   

                                                   

                                                   

                                                   

                                                   

                                                   


                                                   


                                                  ラズパイで定点カメラ

                                                  0

                                                    ラズパイで定点カメラ

                                                     

                                                    JUGEMテーマ:電子工作

                                                     

                                                    訳有って監視カメラを取り付ける事にしたんですが、見積もりを取ったところ60万と出て来まして
                                                    必要に迫られましてラズパイでカメラを作ってみる事にします。

                                                    色々と調べたんですが、arduinoの場合は処理速度と記録容量の問題でNG
                                                    価格との兼ね合いでRaspberryPIで作ってみることにします。

                                                    今回はプロトタイプとしてRaspberryPi3とラズパイカメラにて一定期間の画像が取得できる事を目標にします。
                                                    将来的にはRaspberryPiZeroに移行して防水の筐体に入れたいと思います。

                                                    ■要求仕様


                                                     最低でも5秒間隔で1週間は保存したい。

                                                     

                                                    ■風景

                                                     

                                                     

                                                    ■セットアップ

                                                     

                                                    ・パイカメラのライブラリをインストール
                                                     sudo apt-get install python-picamera

                                                     

                                                    ■【検証1】静止画を保存

                                                     

                                                    import picamera
                                                    camera=picamera.PiCamera()
                                                    camera.capture('image.jpg')

                                                    この状態だと左右が逆になるようなので調べると

                                                    #左右反転
                                                    camera.hflip = True
                                                    #上下反転
                                                    camera.vflip = True

                                                    他にもパラメーターありそうなので調べると以下の物もあり
                                                    #camera.resolution = (1920,1200)
                                                    #camera.sharpness = 0
                                                    #camera.contrast = 0
                                                    #camera.brightness = 50
                                                    #camera.saturation = 0
                                                    #camera.ISO = 0
                                                    #camera.video_stabilization = False
                                                    #camera.exposure_compensation = 0
                                                    #camera.exposure_mode = 'auto'
                                                    #camera.meter_mode = 'average'
                                                    #camera.awb_mode = 'auto'
                                                    #camera.image_effect = 'none'
                                                    #camera.color_effects = None
                                                    #camera.rotation = 0

                                                    ・今回はサイズ左右反転とサイズのみ指定して以下の様にした。

                                                    import picamera

                                                    camera=picamera.PiCamera()
                                                    camera.hflip = True
                                                    camera.resolution = (640,480)
                                                    camera.capture('image_mono.gif')

                                                     

                                                    ■【検証2】動画を画面に表示

                                                     

                                                    import picamera
                                                    import time

                                                    camera=picamera.PiCamera()
                                                    #左右反転
                                                    camera.hflip = True
                                                    camera.resolution = (640,480)
                                                    #動画表示開始
                                                    camera.start_preview()
                                                    #10秒間の動画
                                                    time.sleep(10)
                                                    #動画表示終了
                                                    camera.stop_preview()
                                                    camera.close()

                                                     

                                                    ■【検証3】動画を保存

                                                     

                                                    import picamera
                                                    import time

                                                    camera=picamera.PiCamera()
                                                    #左右反転
                                                    camera.hflip = True
                                                    camera.resolution = (640,480)
                                                    #動画を保存開始
                                                    camera.start_recording('record.h264')
                                                    #10秒間の動画
                                                    time.sleep(10)
                                                    #動画を保存終了
                                                    camera.stop_recording()
                                                    camera.close()

                                                    record.h264で保存されるのでmp4に変換

                                                    ・gpacをインストール
                                                    sudo apt-get install -y gpac
                                                    ・コマンドでmp4に変換
                                                    MP4Box -fps 30 -add record.h264 record.mp4

                                                     

                                                    ■【検討】上記の検証で判ったこと


                                                     静止画の保存でRaspberryPi3で実行した場合で640×480サイズでGIFで保存して220KByteで約3秒。
                                                     動画の保存でRaspberryPi3で実行した場合で640×480サイズで10秒で1.8MByte。
                                                     動画では32GのSDで3.5時間分しか記録できないので静止画しか選べない

                                                     

                                                    ■容量設計


                                                     ラズパイのマイクロSDの容量を32GByteとする。
                                                     OSシステムの容量を4GByteとしてデータとして28GByte使えるとする。
                                                     写真のサイズを640×480として
                                                     GIFで保存して220KByteとして
                                                     5秒間隔で1週間だと
                                                      7日間 × 24 時間 × 60分 × 12(1分の枚数) × 220KByte
                                                      計算の答え
                                                      約25GByte
                                                     3GByteは予備って事で大丈夫って事にした。
                                                     64GByteのSDなら2秒単位でもOKですね。
                                                     128GByteならば2秒単位でも2週間以上保持可能です。

                                                     

                                                    ■ディレクトリ構成


                                                     /home/pi/picamera
                                                           camera.py
                                                           camera.sh
                                                           /data
                                                             /YYYYMMDD (日付20181224等)
                                                               HHMMDD (時刻091824等)

                                                     

                                                    ■プログラム


                                                    ・camera.py


                                                    import picamera
                                                    import datetime
                                                    import os

                                                    #ディレクトリとファイル名を作成
                                                    now = datetime.datetime.now()
                                                    base_directory = '/home/pi/picamera/data/'
                                                    YYYYMMDD = now.strftime('%Y%m%d')
                                                    output_directory = base_directory + YYYYMMDD
                                                    if not os.path.exists(output_directory):
                                                      os.makedirs(output_directory)
                                                      os.chmod(output_directory, 0777)
                                                    filename = now.strftime('%H%M%S')
                                                    filename_fullpath = output_directory + '/' + filename + '.gif'

                                                    #カメラを起動して保存
                                                    camera=picamera.PiCamera()
                                                    camera.hflip = True
                                                    camera.vflip = False
                                                    camera.resolution = (640,480)
                                                    camera.capture(filename_fullpath)

                                                    camera.close()

                                                     

                                                    ・解説


                                                    日付と時刻からディレクトリとファイル名を生成して
                                                    静止画を保存する


                                                    ■起動シェル


                                                    ・camera.sh


                                                    find /home/pi/picamera/data/* -name '*.gif' -ctime +7 -exec rm -f {} ¥;
                                                    find /home/pi/picamera/data/* -type d -ctime +7 -exec rm -rf {} ¥;
                                                    python /home/pi/picamera/camera.py

                                                    ・解説
                                                    1週間経過したファイルを削除
                                                    1週間経過したディレクトリを削除
                                                    camra.pyを起動

                                                     

                                                    ■クーロン設定


                                                    ・crontab -e


                                                    * * * * * for i in `seq 0 5 59`;do (sleep ${i}; /home/pi/picamera/camera.sh) & done;

                                                     

                                                    ・解説


                                                    先頭部の「* * * * * 」は毎分00秒にcronで実行
                                                    実行するコマンドは「for i in `seq 0 5 59`;do (sleep ${i}; /home/pi/picamera/camera.sh) & done;」

                                                    縦に書くと以下の様になり
                                                    for i in `seq 0 5 59`;
                                                    do (
                                                      sleep ${i};
                                                      /home/pi/picamera/camera.sh) & 
                                                    done;

                                                    一定時間sleepしてからcamera.shを起動するコマンドを60個実行する
                                                    となる。

                                                     

                                                    ■取得した写真

                                                     

                                                     

                                                    ■トラブル

                                                     

                                                    上記で実行していたところ、1時間実行したぐらいのところで

                                                    「camera=picamera.PiCamera()」がエラーになり実行できなくなった。

                                                    調べたところ、RaspberryPIを最新化することで解決できるようなので以下のコマンドを実行。

                                                    sudo apt-get update
                                                    sudo apt-get upgrade
                                                    sudo apt-get dist-upgrade
                                                    sudo rpi-update
                                                    sudo reboot

                                                     

                                                    その後は9時間経過しても今のところ安定。

                                                     

                                                     

                                                     

                                                     


                                                    マイクロ波レーダーセンサーでRCWL-0516で人感センサーを試す

                                                    0

                                                      マイクロ波レーダーセンサーでRCWL-0516で人感センサーを試す

                                                      ドップラーレーダーRCWL-0516を使用した人感センサーの実験記事です。

                                                       

                                                      ■ドップラーレーダーを調べてみると
                                                       ドップラーレーダー(Doppler radar) は発信した周波数と反射してきた周波数(波長)の違いも測定して対象物がレーダーから遠ざかっているのか、近ずくのかを測定することで、対象物までの距離と移動速度を推定(ドッブラー効果を利用)することも出来ます。

                                                       

                                                      参考URL
                                                      http://www.geocities.jp/hiroyuki0620785/intercomp/wireless/radargen.htm

                                                      という事のようです。つまり、


                                                      ■一定の周波数の電波を発射する。電波が対象物に当たると電波が反射してくる。
                                                      反射してきた周波数を測定。物体が遠ざかっていれば元の周波数より低くなり、物体が近づいていれば元の周波数より高くなる。
                                                      反射してきた周波数から物体が動いていることを検出する。という事らしいです。
                                                      そんな凄い物がたった数百円で手に入るなんて。いい時代になりましたね。

                                                       

                                                      ■手に入れた物がこれ

                                                       

                                                       

                                                       

                                                       

                                                       

                                                       

                                                      物体を検出した場合にLEDを光らせる実験を行い、実際に人の検知が何メートル先まで可能か実験してみます。

                                                       

                                                      ■ピンアサイン

                                                      3V3 : 3.3V安定化出力。他のデバイスの電源としては使用できない
                                                      GND : グラウンド 電源0V 
                                                      OUT : 信号線 検出時=3.3V、未検出時=0V。未検出になってから3秒間は3.3Vを保持する
                                                      VIN : 電源 5V〜12V
                                                      CDS : CDSの出力(CDS接続時)デフォルトでは未接続

                                                       

                                                      参考URL
                                                      本家 http://forum.hobbycomponents.com/viewtopic.php?t=2181
                                                      翻訳 https://plaza.rakuten.co.jp/v62000/diary/201801030000/

                                                       

                                                      ■回路図

                                                       


                                                      5Vで動作確認した場合は検知距離が非常に短かったので12Vにて作成

                                                       

                                                      ■動画

                                                       

                                                       

                                                      動くものに敏感に反応して3秒ぐらい信号を出す。

                                                       

                                                      ■測定方向

                                                       


                                                      基盤の裏面の丸いパターンから電波を発射および受信していると思われます。

                                                       

                                                      ■実験結果

                                                      結果 5.1メートル
                                                       手を組んだ状態でスクワットをした人間を検知可能

                                                       

                                                      JUGEMテーマ:電子工作


                                                      焦電型赤外線センサSB412Aで人感センサーで人間を検知する。

                                                      0

                                                        焦電型赤外線センサSB412Aで人感センサーで人間を検知する。

                                                         

                                                        マイコンを接続せずにLEDを点灯させます。

                                                        ■SB412Aについて

                                                         


                                                        写真の通り3つの端子が付いております。
                                                        電源電圧は5V。
                                                        人感センサーが反応したときにOUTに3Vになります。
                                                        反応なしの場合は0Vになります。
                                                        一旦反応した場合はデフォルトではOUTの3Vが10秒間続く。
                                                        この時間は基盤の可変抵抗で最長60分程度まで延長可能。
                                                        参考URL
                                                        http://akizukidenshi.com/catalog/g/gM-09002/

                                                         

                                                        ■回路図

                                                         

                                                         

                                                        ■動画
                                                        https://youtu.be/umaZ552pg7w


                                                        ■実験結果

                                                        結果 2.8メートル
                                                         手を組んだ状態でスクワットをした人間を検知可能

                                                         

                                                        ■AKE-1と比較したときに

                                                        オペアンプで増幅しなくても済む分非常に楽です。

                                                        その分はお値段も張りますけどこっちをお勧めします。

                                                        JUGEMテーマ:Arduino

                                                        JUGEMテーマ:電子工作

                                                         


                                                        炎センサーモジュール(DFR0076)で炎を検出する

                                                        0

                                                          炎センサーモジュール(DFR0076)で炎を検出する

                                                           

                                                          昨日に引き続き炎センサーに関する記事です。
                                                          炎センサー探しに秋葉をぶらついていたんですが、秋月にその名もFrameSensorなるセンサーがあるではないですか。
                                                          早速購入。

                                                          仕入れてから時間が経ちましたが、記事にまとめておきたいと思います。
                                                          参考URL
                                                          http://akizukidenshi.com/catalog/g/gM-07041/

                                                           

                                                           

                                                           

                                                          秋月ページとメーカーページを見ると20cmで検出すると4.8V、100cmで検出すると1.0Vとなっております。
                                                          あまり遠くまでは検出できない模様。ちょっと残念ですがテストしてみたいと思います。

                                                           

                                                          ■回路

                                                           

                                                           

                                                          簡単です。
                                                          電源の接続とDFR0076の信号線をarduinoのアナログリードへ接続するのみです。

                                                           

                                                          ■プログラム
                                                          int sensorPin = A0;

                                                          void setup() {
                                                            pinMode(13, OUTPUT);

                                                            Serial.begin(9600);
                                                            Serial.println("ver1.0");
                                                            Serial.println("start:");

                                                          }

                                                          int nCount=0;
                                                          void loop() {
                                                            char szStr[30];
                                                            
                                                            sprintf(szStr, "%d¥n", nCount);
                                                            Serial.print(szStr);
                                                            nCount++;

                                                            int sensorValue = analogRead(sensorPin);
                                                            sprintf(szStr, "sensor value = %d¥n", sensorValue);
                                                            Serial.print(szStr);

                                                            if(sensorValue>200){
                                                                digitalWrite(13, HIGH);
                                                            }
                                                            else{
                                                              digitalWrite(13, LOW);
                                                            }
                                                           
                                                            delay(1000);
                                                          }

                                                          センサーからの電圧変化をA0からanalogReadしてその値が200以上でLED点灯、それ以外は消灯とします。
                                                          analogReadの信号線A0に5Vを与えると1023の数値が出ますので5V÷1024=0.0049なので
                                                          値が1変化すると5ミリボルトの変化になります。
                                                          仕様によると1メートルの位置で検出した場合に1.0ボルトとなりますので、
                                                          200は丁度1メートルの位置で検出となります。

                                                           

                                                          ■動画


                                                          ■実験1:ライター(炎小さい)

                                                          ライターの炎(高さ30ミリ。幅5ミリ)
                                                          記録:77センチメートル

                                                          ■実験2:カセットコンロ火力最強(高さ10センチ、幅10センチ)
                                                          記録:検出不可能
                                                          これは意外な結果ですが、カセットコンロのカセットボンベには「LPG液化ブタン」と書いてありますがガスの種類などによっては炎の発出する光の波長(近赤外線)が異なるのでしょう。

                                                          JUGEMテーマ:電子工作


                                                          UVtronで炎を検知する

                                                          0

                                                            UVtronで炎を検知する

                                                            炎を検知する方法を調べていたところ浜松ホトニクス社のUVtronとその駆動回路にて炎を検知できる事が判りましたので取り寄せて実験してみることにしました。
                                                            参考URL
                                                            http://eleshop.jp/shop/g/gF2H123/

                                                            今回使用したのはUVtron R2868とその駆動回路C10807-01です。

                                                             

                                                             

                                                             

                                                            ■制作

                                                            届いた説明書を参考にしてオープンコレクタ出力の2でテストしていたんですが、
                                                            こちらは回路が入っていない様です。
                                                            参考URL
                                                            https://www.hamamatsu.com/resources/pdf/etd/C10807_TPT1025J.pdf
                                                            2ページのNOTEに記述がありました。「C10807-01/02はオープンコレクタ出力(2)は出力されません」
                                                            これは罠ですね。

                                                            これが判らなくて壊れたのかと思いビビりまくりです。

                                                            とりあえず、動く回路を掲載します。

                                                             


                                                            ちなみに、C10807-01のCXコンデンサ追加点には1μFの電解コンデンサーを追加しています。
                                                            これで、大体1秒です。

                                                            回路は簡単で
                                                            炎を検知したらLEDが光るという単純明快なものです。


                                                            ■動画


                                                            ■実験1:ライター(炎小さい)

                                                            ライターの炎(高さ15ミリ。幅5ミリ)
                                                            記録:3.4メートル

                                                            ■実験2:カセットコンロ火力最強(高さ10センチ、幅10センチ)
                                                            記録:6.9メートル以上
                                                            私の住居ではこれ以上の距離を測定するのは無理。測定限界。

                                                            ■実験3:カセットコンロ火力とろ火(高さ1.5センチ、幅10センチ)
                                                            記録:4.5メートル

                                                             

                                                            JUGEMテーマ:趣味

                                                            JUGEMテーマ:電子工作

                                                             


                                                            | 1/7PAGES | >>

                                                            PR

                                                            calendar

                                                            S M T W T F S
                                                              12345
                                                            6789101112
                                                            13141516171819
                                                            20212223242526
                                                            2728293031  
                                                            << October 2019 >>

                                                            selected entries

                                                            仙台市小松島の賃貸アパート紹介

                                                            categories

                                                            archives

                                                            recent comment

                                                            recent trackback

                                                            profile

                                                            search this site.

                                                            others

                                                            mobile

                                                            qrcode

                                                            powered

                                                            無料ブログ作成サービス JUGEM