読者です 読者をやめる 読者になる 読者になる

RPiでRAMディスクに画像保存&別マシンから1fps程度の画像閲覧

RAMディスクを用意

Raspberry PiのSDカード/マイクロSDカードの寿命を延ばす | ものづくりエクスペリメント

これをみてdphys-swapfileをapt-get remove

スワップファイルというのは

スワップとは|swap : 意味/定義 - IT用語辞典

課題とは関係ないけれどもSDカードの寿命を伸ばすために、/tmp等をRAMディスクにするというのもやっておいたほうがよさそう。これはあとでやる。

SDカードをすべてリードオンリーにするということもできる。これはシステムが出来上がってからやったらよいのかもしれない。

Raspberry Pi でfsprotectを試す | よもやま雑記帳

RAMディスクをどこにどう作るか

Linux Tips – RAMディスク(/dev/shm)のIO性能をチューニングに活用する方法

Linuxキーワード - RAMディスク:ITpro

このへんを見ると/dev/shmをそのまま使ってもよさそう

新たに作るならこれが参考になりそう

マイクラ鯖に持って来い!!、LinuxでRAMディスク!! | 純規の暇人趣味ブログ

シャットダウン時にデータが消えないようにSDカードに書くという動作を加えるというやり方も書いてある。電源が急に切れた場合に対応するにはcronで一日おきにsdカードに保存するなど。

 

Raspberry Pi 3にssh接続

connection refusedと出たが、下記を見て、raspi-configを実行してsshを有効にしたら接続できるようになった

pi 3 - No SSH (Connection refused) using raspbian with pixel - Raspberry Pi Stack Exchange

 

USBカメラ画像を取得して保存&ソケットで画像を飛ばす

Cでデバイスファイル開いて扱ってもいいが、 OpenCVを使うことにする。

Cプログラミングによる画像処理(1)

pythonでやることにする。

$ sudo apt-get install libopencv-dev

$ sudo apt-get install python-opencv

Raspberry Pi で OpenCV(リベンジ) - Qiita

ここのテストプログラムは動いた。

Pythonによる通信処理 - Qiita

これでとりあえずソケットの形に。複数接続するには

socketプログラムの初歩から初める - Keep on moving

  1. threadを使う
  2. forkする
  3. selectなどを使う

の三つがあるそう。selectを使うのはこんな感じ

Pythonでネットワークプログラミング | saito's memo

 windows側からpython実行するのに下記のやり方をググった。

import os

os.chdir("C:\\ほげほげ")

os.getcwd()

execfile("hoge.py")

 windowspythonにnumpyをインストール

WindowsでPython3, numpy, pandas, matplotlibなどインストール - Qiita

> python -m pip install numpy

これでインストールできた

import cv2.cv as cvではなくimport cv2だけで使えるように下記のを参考

Python+OpenCVでカメラキャプチャ - Qiita

ソケットで画像を飛ばすのは下記

OpenCVでRaspberry Piから画像を転送する - kivantium活動日記

 ソケットで接続するWindows側クライアント

 クライアントはCSでwinのformで作る。文字列にエンコードしたjpegをデコードする。

TCPクライアント・サーバープログラムを作成する: .NET Tips: C#, VB.NET

デリゲートについて

デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

マルチスレッドについて。threadやtaskやasync/awaitを使う方法があるらしい。このうちTaskと、async/awaitが現行のやり方でそれ以外は古いらしい。

ThreadじゃなくTaskを使おうか? - Qiita

Taskを極めろ!async/await完全攻略 - Qiita

できる!C#で非同期処理(Taskとasync-await) – kekyoの丼

マルチスレッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

 書き方の例

[C#]ざっくりマルチスレッド(非同期処理) – gomokulog

[C#]async/awaitの使い方メモ、その1。 | Kimux.Net

別スレッドからフォームのコントロールにアクセスするのはスレッドセーフではないらしい

方法 : Windows フォーム コントロールのスレッド セーフな呼び出しを行う

排他処理のやり方も気を付ける必要があるらしい

.NET TIPS:非同期:awaitを含むコードをロックするには?(SemaphoreSlim編)[C#、VB] - @IT

→timerを使えば解決

だけど、スレッドを使えるようになりたいのでそれはそれであとで勉強しておく

複数カメラの接続はserver*.pyを複数立ち上げることで実現することにする。シェルスクリプトでやる。

pgrepという便利コマンドがある

pgrep, pkill を使用してプロセスを殺す - 技術メモ帳

kill `pgrep -f hogehoge`とpkill -f hogehogeとは同じかもしれない。

 

 ソケットでの画像の送受信のやり方について

受信バッファの準備ができないうちに送信したり、受信しないうちに受信バッファを読み込みに行ったりしているのではないか。その問題を解決するのに、1)受信バッファのサイズを十分な大きさに指定する 2)アプリケーションレイヤでハンドシェークする というののいずれかをすればよいだろうということでこれの様子をみる。

1)受信バッファのサイズを指定する

Win32APIの(?)Winsockで、ポートごとのバッファの設定ができるのか調べた。

setsockopt function (Windows)

これのSO_RCVBUFが関係しそう

受信バッファ - odawaraの「はてな de メモ」

 

そもそもソケット通信がよくわかってない

ƒ\ƒPƒbƒg

バイナリとアスキーではどちらのほうがサイズが大きいのか?→パッと調べたところではバイナリのほうがデータが大きい場合もあるようなので、ファイルの詳細な形式によるということだと思う。

SocketのReceiveBufferSizeプロパティでbufferサイズはいじれる模様

Socket.ReceiveBufferSize プロパティ (System.Net.Sockets)

 

INIファイルの読み込み

C#.NET Tips

 

サーバ側でカメラをホットプラグにする処理

opencvのエラーをキャッチできないためにカメラを抜いた状態で

g_capture.read()をしてもret1やframeが直前の状態(ret1 = True)をキープしてしまい、カメラの接続が外れたことを検知できない。

しかたないので、pythonからシェルスクリプト実行して/dev/video*の存在を見ることでデバイスの接続有無を判定するようにした

 

サーバ側の画像保存を厳密に一定時間になるように時間の制御を加えた

 

Rapsberry piのカメラ画像の表示処理結果に遅延→カメラ画像取得に遅延?

OpenCVでバッファリングしてるところがあるのでそこでのバッファをしないという風にする↓の方法を試してみる

OpenCV カメラの遅延の対策 | ぴよちゃんの工房