OWLIFT Type-Fの勘所 第2回 / 安定した出力を得るアルゴリズム
前回はシャッター開閉の影響について説明しました。
今回はシャッター開閉の影響をなるべく避けて温度を取得する方法と、併せて安定した出力を得るためのコツについて紹介します。
シャッター開閉のタイミングを避けて温度を取得する
以下にシャッターの影響が最小限になるよう1分ごとに温度を取得するサンプルプログラムを示します。
import sys
import owlift
AVERAGE_FRAMES = 9
EMISSIVITY_R4 = pow(0.95, -0.25)
# 計測する範囲の座標: (rx[0], ry[0])-(rx[1], ry[1])
rx = [75, 85]
ry = [55, 65]
# 計測を開始するシャッター開閉後からの経過時間(秒)
obs_dts = [58, 118, 178]
# 計測したフレーム数
obs_frames = 0
# 計測中かどうか
obs_calc = False
# 計測中の温度合計値
temp_sum = 0
# 前回のフレームカウンタ
fc0 = 0
ow = owlift.devices()[0]
ow.capture_start()
print("Time DTime Temp")
while ow.alive:
fc = ow.frame_counter
if fc == fc0:
continue
fc0 = fc
temp, img, meta = ow.frame
telem = meta.telemetry_data
tc = telem.time_counter
dt = (telem.time_counter - telem.ffc_time_counter) / 1000
if obs_calc:
# 指定範囲の平均を加算
temp_sum += temp[ry[0]:ry[1], rx[0]:rx[1]].mean()
obs_frames += 1
if obs_frames == AVERAGE_FRAMES:
# 複数フレームの平均
temp_avg = temp_sum / obs_frames
# 放射率で補正してケルビンを摂氏へ変換
temp_avg = temp_avg * EMISSIVITY_R4 - 273.15
obs_calc = False
print("{:6.0f} {:3.0f} {:5.1f}".format(tc / 1000, dt, temp_avg))
else:
for odt in obs_dts:
# odtから1秒以内に計測を開始する
if odt <= dt and dt < odt + 1:
obs_calc = True
obs_frames = 0
temp_sum = 0
実行例
>python periodic-temp.py
Time DTime Temp
1233 179 30.1
1296 59 30.2
1356 119 30.1
1416 179 30.3
1479 59 30.7
1539 119 30.4
1599 179 30.4
1662 59 30.5
シャッター開閉後からの経過時間 obs_dts で指定した時間になると、複数のフレームの平均値を出力します。
obs_dts を [58, 118, 178] としているのは、次の条件を満たすように決めたからです。
1) 60秒ごと
2) シャッター開閉後の山なりの部分を避ける
3) 1秒間データを取得してもシャッター開閉のタイミングにかからない
安定した出力を得るコツ
上記のプログラムには安定した出力を得るための、いくつかのアルゴリズムが含まれているので説明します。
■ 範囲の平均を計算する
計測対象を点ではなく範囲(複数ピクセル)の平均で計算します。熱画像には一定の割合でノイズが含まれているため、複数のピクセルを平均することでノイズの影響を少なくします。
■ 複数フレームの平均を計算する
出力は短時間の間に揺らいでいるので、1フレームではなく複数フレームの平均を計算することで、より安定した温度値を得ます。ここでは9フレーム(約1秒間)を平均しています。
■ 放射率を適用する
コツというより赤外線で温度を計測するときの一般的な手順なのですが、センサから得た出力に放射率εの-0.25乗 (EMISSIVITY_R4) を掛けて補正します。放射率は計測対象によって異なるので適切な値を指定してください。
実行時の注意点
実行する際はOWLIFTをUSBに接続してから20分以降のデータを取得してください。OWLIFT本体がある程度温まるまでは出力が安定しません。