今回は, FLIR ONEを使って, 写したものの温度を測定してみようと思う.
2. 温度測定[1][2][3]
ImageTypeに"ThermalRadiometricKelvinImage”を指定すると"Radiometric centikelvin(cK) tmperature data"が取得できる.
セルシウス温度tとそれに等しい絶対温度Tとの間には以下の関係があり, 温度(℃)を求めることができる.
t/℃ = T/K - 273.15
(1) ImageTypeの設定
[コード]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mOverlayView = (OverlayView)findViewById(R.id.overlay_view_id);
mThermalView = (ImageView)findViewById(R.id.thermal_view_id);
mThermalView.setRotation(180.0f);
RenderedImage.ImageType defImageType = RenderedImage.ImageType.BlendedMSXRGBA8888Image;
RenderedImage.ImageType kelvinlImageType = RenderedImage.ImageType.ThermalRadiometricKelvinImage;
mFrmProcessor = new FrameProcessor(this, this, EnumSet.of(defImageType, kelvinlImageType));
}
(2) 温度に変換
[コード]
public void onFrameProcessed(RenderedImage renderedImage) {
Log.i(LOG_TAG, "Frame processing!");
if (renderedImage.imageType() == RenderedImage.ImageType.BlendedMSXRGBA8888Image) {
mThermalBitmap = renderedImage.getBitmap();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mThermalView != null) {
mThermalView.setImageBitmap(mThermalBitmap);
}
}
});
}
else if (renderedImage.imageType() == RenderedImage.ImageType.ThermalRadiometricKelvinImage) {
calcTemperature(renderedImage); // 画像中央の温度計算
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mOverlayView != null) {
mOverlayView.drawTemperature(mOverlayView.getWidth()/2, mOverlayView.getHeight()/2, mAveTemperature);
}
}
});
}
}
// 画面中央の10x10エリアの平均温度
private void calcTemperature(RenderedImage renderedImage) {
final int AREA_SIZE = 10;
int width = renderedImage.width();
int x0 = (width - AREA_SIZE) / 2;
int y0 = (renderedImage.height() - AREA_SIZE) / 2;
double averageTemp = 0.0;
short[] shortPixels = new short[renderedImage.pixelData().length / 2];
ByteBuffer.wrap(renderedImage.pixelData()).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortPixels);
for (int y = y0; y < y0 + AREA_SIZE; y++) {
for (int x = x0; x < x0 + AREA_SIZE; x++) {
// 注) データはunsigned shortなのでintに変換して加算
averageTemp += (int)(shortPixels[width*y + x] & 0xffff);
}
}
averageTemp /= (AREA_SIZE * AREA_SIZE);
mAveTemperature = averageTemp / 100 - 273.15;
}
[実行結果]
- Nexus 7 (2013) / Android 4.4.4
とりあえず, 画面中央の位置の物の表面温度を測定できるようになった.
ただ, この表示温度がどこまで正確な温度かは別の問題である.
正しく温度を測定するためには, 測定する物質に合わせて放射率(Emissivity)を正しく設定するなど, いろいろと条件設定が必要そうだ...
----
参照URL:
[1] ケルビン - Wikipedia
[2] FLIR One SDK Documentation
[3] FLIR One Software Development Kit