RaspberryPi
全天空カメラ
 今の天気を調べるには、空全体を見上げるのが一番です。魚眼レンズをもったカメラで全天空を写すカメラを自作します。最近市販品が出ていますが、激しい降雨、直射日光、高温など過酷な環境に長期間耐えられるか心配なため、カメラモジュール、魚眼レンズ、RaspberryPiを用いて、自作します。 不具合は部分取り換えができます。(2023/07/15掲載)

RaspberryPiのカメラ
 数年前から半導体不足でこのRaspberry Piの入手が困難になっていました。産業用を優先してきたようで、われわれのようなアマチュアには回ってきませんでした。ようやく正規ルートでPi3モデルA+が入手できました。Pi3モデルA+は安価ですが十分な性能でコンパクト、WiFi、HDMIがつかえます。
 Raspberry Piにはカメラポート用CSI (Camera Serial Interface)コネクタがあり、リボン状のフレキシブルフラットケーブル(FFC)でカメラモジュールと接続します。純正カメラモジュールは現在Camera Module 3が最新です。また、さまざまなサードパーティ(たとえばこちら)からカメラモジュールが市販されており、自作を楽しむことができます。
 カメラモジュールは後で述べる防水ケースに入ること、標準的なM12マウントレンズがつけられること、HDR(High Dynamic Range)が使えることから、Arducam 12MP IMX708 HDR 120°Wide Angle Camera Module with M12 Lens for Raspberry Pi を用いることとしました。またレンズは視角220°魚眼レンズとしてEntaniyaのRP-L220に交換します。
 しっかりした防水は必須です。Entaniya のRaspberryPi カメラV2・V3用 全天候型ケースを用います。

Raspberry Pi 3 Model A+
SoC: Broadcom BCM2837B0
CPU: ARM Cortex-A53 1.4GHz クアッドコア 64ビット
メモリー: 512MB LPDDR2 SDRAM
無線LAN: 2.4 GHz、5 GHz IEEE 802.11.b / g / n / ac
Bluetooth: Bluetooth 4.2
最大消費電力: 約12.5W
サイズ: 65 × 30mm
重量: 29g
参考価格: KSY 4,620円

Arducamカメラモジュール
12MP IMX708 HDR 120°Wide Angle Camera Module with M12 Lens for Raspberry Pi

Image Sensor: ソニー IMX708
Resolution: 11.9MP
Optical Size: 1/2.43(7.4mm sensor diagonal)
Number of effective pixels: 4608(H) × 2592(V)
Pixel Size: 1.4μm × 1.4μm
Interface MIPI CSI-2 Interface
Shutter Type: Rolling Shutter
Common Video Mode: 1080p50, 720p100, 480p120
Output Format: RAW10
参考価格: $ 36.99(直販)

Entaniya 視野220度の魚眼レンズ
RP-L220
センサーサイズ: 1/4″
視野角(1/2.3″): V:220° H:220° D:220°
F値: F2.0
レンズ構成: ガラスレンズ x 2 プラスチック x 4
イメージサイズ: φ2.80mm
有効焦点距離: 0.76mm
マウント: M12 x P0.5
参考価格: 3,718円(直販)

Entaniya
RaspberryPi カメラV2・V3用 全天候型ケース
製品名: Entaniya Waterproof Case WC-01
重量: 36g(カメラ含まず)
同梱品: レンチ、ケース、各種ネジ、六角、乾燥剤
参考価格: 5,852円(直販)

カメラの工作
1号機
防水ボックスの蓋に全天候ケースを取り付ける FFCケーブル用の穴 アクリルドームの内側に結露

2号機
ボックス蓋の上面にアクリル板 
アクリル板に全天候ケースを取り付け
FFCはボックス本体と蓋の間に
はさみこむように挿入
結露なく強烈な逆光でも、まずまずの画質

当初、1号機のようにタカチの 防水型 BCASプルボックス にRaspberry Piをいれ、蓋を加工し、FFCケーブルを通すようにしました。加工精度が悪かったせいか、どうしても水の侵入を防げず、また一度入った水分が蒸発し、全天候ケースのアクリルドームの内側で結露し、画面が汚くなるので、断念。
次に2号機のように、未来工業のPVKボックスの外側にアクリル板を付け、それに全天候型ケースをねじ止めし取り付けました。FFCケーブルは蓋とボックス本体の間に挟み込むように挿入しました。FFCケーブルは薄いのでほとんどすきまはできません。数か月の間、強い雨もありましたが、雨の侵入はありません。

ゴムのシール用ブッシュにカッターで切れ目 USBジャックをつけたままボックス内部にケーブルを通せる

Raspberry Piへの給電ケーブルはケーブルグランドをUSBコネクタをつけたまま通すことのできるように、シール用ブッシュにカッターでスリット加工しました。

全天空カメラをどこに設置するか、悩ましいところです。なるべく空だけを写したいので、高所に設置したほうがいいのですが、老人が屋根に上るのは危険なので、ベランダに2mのポールをたて、そこに設置しました。北側の立木、隣の家が少々写りこんでいます。

設定とソフトウェアの準備
(1) Raspberry Pi
Raspberry Pi カメラのための新しいソフトウェア ライブラリlibcamera を用います。Raspberry Piの最新のOS Bullseyeにはすでにインストールされています。 Raspberry Pi カメラを自動的に検出し、有効になります。
Bullseye OSのインストールは、Raspberry Pi Imagerを用いて行います。今回Raspberry Pi のウィンドウは使いませんので、最小構成のRaspberry Pi Lite(32bi)をインストールしました。

はじめに/boot/config.txtファイルのカメラ構成を変更する必要があります。上記ソニーイメージセンサーimx708を用いているカメラの場合
# Automatically load overlays for detected cameras
camera_auto_detect=0
dtoverlay=imx708
これをエディタをつかって、/boot/config.txtに追記します。

libcameraには様々なコマンドがありますが、たとえば静止画をファイルに1枚記録する場合は
$ libcamera-jpeg -o test1.jpg
試してみます。test1.jpgを開いて静止画が格納されていることを確かめます。
l
ボードに接続されている利用可能なカメラを調べるためには--list-camerasオプションを使います。このオプションには、各カメラがサポートするセンサー モードもリストされます。例えば:
$ libcamera-jpeg --list-camera
Available cameras
-----------------
0 : imx708 [4608x2592] (/base/soc/i2c0mux/i2c@1/imx708@1a)
  Modes: 'SRGGB10_CSI2P' : 1536x864 [30.00 fps - (0, 0)/0x0 crop]
                    2304x1296 [30.00 fps - (0, 0)/0x0 crop]
                    4608x2592 [30.00 fps - (0, 0)/0x0 crop]

libcamera-vid
コマンドはビデオキャプチャアプリケーションです。Raspberry Piにはハードウェア H.264 エンコーダそなわっていて、ハードで動画のエンコードができます。TCPを使用して動画のストリーミングを行い、ホストに送ることとします。
libcamera-vidのパラメータを試行錯誤の結果つぎのようにきめました。シェルスクリプトwidecamera.shをつくっておきます。このシェルスクリプトを実行すると、受信コンピュータからの接続を待ち受け状態になります。

#!/bin/sh
libcamera-vid -v 0 -t 0 --inline --listen -o tcp://0.0.0.0:8081 --framerate 5 --rotation 180 --tuning-file /usr/share/libcamera/ipa/raspberrypi/imx708_wide.json --width 832 --height 642

パラメータは次のとおりです。
-v 0 :デバッグメッセージ出さない
-t 0
:タイムアウト無制限
--inline:ストリーム ヘッダー情報なし
--listen :TCP/IP を使用してネットワーク経由でストリーミングすることを示します。受信クライアントからの接続を待機します。
-o tcp://0.0.0.0:8081:アウトプットファイル名。tcpストリームのポート番号を指定。
--framerate 5:1秒当たりのフレーム数 WiFiへの負荷低減のため
--rotation 180:天空画面の上が北、下が南になるように、画面を回転
--tuning-file :チューニングファイルを指定。チューニングファイルはさまざまな種類のカメラ モジュールごとに、最高の画質を生成するためにアルゴリズムとハードウェアに渡されるパラメータを記述または「調整」するファイルです。json形式で記述され/usr/share/libcamera/ipa/raspberrypiにいくつかチューニングファイルがあるので、その中から指定します。 ここではimx708_wide.jsonを使用
--width 832 --height 642:imx708イメージセンサーは4608 × 2592ピクセル数ですが、伝送、保存の都合上、解像度を下げて使います。

(2) VLCメディアプレーヤー
VLCメディアプレーヤー(VLC media player, VideoLAN Client)は、様々なOSで動作するメディアプレーヤーです。非常に多くのメディアファイル用コーデックが内蔵されており、動画ファイルや音声ファイルなど多くのメディアファイルを再生、表示することができます。Raspberry Pi から送られてくるH264のTCPストリームにも対応しています。Windowsマシンに公式サイトからダウンロード、インストールします。

まずH264のTCPストリームをVLC media playerで見えるようにします。上記Raspberry Piでwidecamera.shを実行しておきます。
VLC media playerを起動し
メニューの「メディア」をクリック
「ネットワークストリームを開く」をクリック
「ネットワークURLを入力してください」のボックスの中にtcp/h264://192.168.x.xxx:8081を記入
再生をクリック
これでRaspberry Pi から送られてくる動画が見えます。

次に連続的に静止画ファイルに記録することにします。次のように設定します。
VLC media playerを開く
メニューの「ツール」の「設定」をクリック
左下の「設定の表示」の「すべて」をクリック
「詳細設定」ダイアログになる
「ビデオ」内の「フィルター」のプルダウンを表示させる
「シーンフィルター」をクリック
右側が「シーンビデオフィルター」設定画面になる
「画像形式」を「jpg」にする
「画像の幅」と「画像の高さ」はデフォルトのまま「-1」とする
「ファイル名のプレフィックス」は、「widecamera」など
「ディレクトリパスのプレフィックス」は、出力フォルダーのパスを記入
「常に同じファイルに出力」にチェック
「レコーディングレシオ」に1分毎、すなわち5フレームX60秒「300」記入
左側の「ビデオ」内の「フィルター」の文字をクリック
右側が「フィルター」一覧表示になる
「シーンビデオフィルター」をクリックしチェックボックスにチェックする
下のテキスト領域内に「scene」と表示される
右下の「保存」ボタンをクリック
これにより出力ファルダ―の中にwidecamera.jpgが1分に1回書かれます。

(3) 静止画をトリミング、タイムスタンプ(プログラム掲載省略 要問合せ)
WindowsマシンでJAVAプログラムにより、次の処理を行います。
1分毎に上記静止画ファイルを読み込み、正方形にトリミング(javax.imageio.ImageIO)
画面左下に記録した時点のタイムスタンプを書き込み(java.awt.Graphics)
1分毎にサイトにアップロード
ファイル名はwidecamera0.jpgからwidecamera9.jpgまで、10分間で一巡するようにします。

(4) web上でパラパラ動画として表示
パラパラ動画は静止画を連続的にめくって動画のように見せることです。こちらを参考にしました。
ホームページのHTMLにおいて次のようなJAVAScriptを、ヘッダーの最後、すなわち </head>の手前に埋め込みます。
ANIMA[i] という配列にwidecamera0.jpgからwidecamera9.jpgをいれます。 anime_1()という関数がよばれると、配列の中身を500msごとにつぎつぎ表示します。
<script language="JavaScript1.1">
<!--
var ImageSetB = 0 ;
ANIMA = new Array(11); 
for(i = 0; i < 10; i++ ) {	
		ANIMA[i] = new Image() ; 
		ANIMA[i].src = "widecamera/widecamera" +  i + ".jpg" ; 	
}
function anime_1() {
	document.animation.src = ANIMA[ImageSetB].src ;
	ImageSetB++ ;
	if(ImageSetB >= 10) {
		ImageSetB = 0 ;
	} 
	setTimeout("anime_1()",500);
}
//-->
</script> 
 


さらに<body><body onload="anime_1();">のように変更し、うえのJAVAScriptを自動起動しパラパラ動画として表示できるようにします。ここでwidecamera_.jpgは最初に表示したい画像です。
 
<body onload="anime_1();">
<img src="widecamera/widecamera_.jpg" name="animation" alt="全天空カメラ" border="0" width="320" height="320">
</body>


このページでも下のようにパラパラ動画を表示していますので、実際のHTMLソースをブラウザで表示し、確認ください。

観測例
直近10分回の静止画面10枚を連続的に表示。
南に向いて空を見上げているように、左が東、右が西になっています。
レンズ、イメージセンサーの汚れのため、あるいはそれによる回折現象のため、一部画面が汚れています。もう少し改善したいと思います。
全天空カメラ

本日、深夜から直近まで、5分毎の記録は、こちら

top