Google OS実験室 ~Moonlight 明日香~

GoogleのAndroidで遊び始めて, すでに6年以上が経った. Androidは思った以上の発展を遂げている. この技術を使って, 新しいことにチャレンジだ!!

VMware Playerを快適にしたい

Google発の深層学習フレームワーク「TensorFlow」のAndroidデモをUbuntu 14.04 on VMware Playerでビルドしようとしたが, 一晩かかっても終わらなかった.

ホストマシン:
 CPU:Intel Core i7-2600K
 RAM:8.00GB
 OS:Windows 10 Pro
 VMware Player 6
仮想マシン:
 プロセッサ数:4
 メモリ:3GB
 HDD:100GB
 OS:Ubuntu 14.04

VMware Playerをもう少し快適にできないかと少し調べてみたところ, 仮想マシンのメモリはデフォルトではHDD(or SSD)上にメモリファイル(.vmem)として置かれるようである.
これならディスクI/Oが多発し動作が遅いのも納得である.

そこで, 仮想マシンで実メモリが使えるように, VMware構成(*.vmx)ファイルでメモリ関連の設定を行うことにした.


1. 設定項目[1][2]
vmxファイルに以下の設定を追加する.
  mainMem.useNamedFile= "FALSE"
  MemTrimRate = "0"
  sched.mem.pshare.enable = "FALSE"
  prefvmx
.useRecommendedLockedMemSize = "TRUE"
  MemAllowAutoScaleDown = "FALSE"

2. 各パラメータの説明[1][2]
1) mainMem.useNamedFile = "FALSE" 
  メモリファイル(.vmem)を使用しない.
2) MemTrimRate = "0"
  メモリページのトリミングを無効にする.
3) sched.mem.pshare.enable = "FALSE"
  ページ共有機能を無効にする.
4) prefvmx.useRecommendedLockedMemSize = "TRUE"
 メモリ使用量が変化した際に, メモリサイズを固定する.
5) MemAllowAutoScaleDown = "FALSE"
  仮想OSのメモリサイズの自動調節を無効にする.

上記設定で, 以前よりビルドの進行は速くなったが, それでもandroid:tensorflow_demoのビルドはなかなか終わらない.
まだディスクアクセスが頻発しているもよう.

task

そもそもVMware Player上でビルドしているからなのか, それともPCのメモリ不足が原因なのか不明.
ビルド時間がもったいないので何とかしたい!!

Deep Learningやるために, 新しいLinux PC組もうかな~.
ああ, Core i7-6700K + 16GB RAM + SSD + NVIDIA GTX980がほしい.

----
参照URL:
[1] VMware Player上の仮想OSを高速化させ軽快に作動させるチューニング
[2] VMX-file parameters


FLIR ONEで遊んでみる(3)

今回は, 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

flir04

flir03

とりあえず, 画面中央の位置の物の表面温度を測定できるようになった.
ただ, この表示温度がどこまで正確な温度かは別の問題である.
正しく温度を測定するためには, 測定する物質に合わせて放射率(Emissivity)を正しく設定するなど, いろいろと条件設定が必要そうだ...


----
参照URL:
[1]
ケルビン - Wikipedia
[2] FLIR One SDK Documentation
[3] FLIR One Software Development Kit

livedoor プロフィール
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

記事検索



  • ライブドアブログ