粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

LucasKanade オプティカルフロー検出 @ MATLAB

この記事はメモです。
中のコードは以下のものをほとんど流用したので自分で書いたとはあまり言い張れないなぁ。
https://jp.mathworks.com/matlabcentral/fileexchange/48744-lucas-kanade-tutorial-example-1/content/LucasKanadeExample1/html/LKExample1.html

関数名:OpticalFlow
入力:前画像,後画像
出力:前画像から後画像へのオプティカルフローを図としてアウトプット

参照元からの変更分

  • 関数への変更
  • Conv()からfilter2()関数の使用への変更

コード

%% Optical Flow
% This is not my original code
% https://jp.mathworks.com/matlabcentral/fileexchange/48744-lucas-kanade-tutorial-example-1/content/LucasKanadeExample1/html/LKExample1.html
% reviced conv() use to filter2

function OpticalFlow(img1,img2)

im1t = im2double(img1);
im1 = imresize(im1t, 0.5);
im2t = im2double(img2);
im2 = imresize(im2t, 0.5);

ww = 45;
w = round(ww/2);

% Lucas Kanade Here
% for each point, calculate I_x, I_y, I_t
fx=[-1,0,1;-1,0,1;-1,0,1];			% フィルタ行列の作成
fy = [-1,-1,-1;0,0,0;1,1,1];
Ix_m=filter2(fx,im1,'same');		% フィルタリングX方向微分
Iy_m=filter2(fy,im1,'same');		% フィルタリングY方向微分
It_m = im2 - im1;

% Ix_m = conv2(im1,[-1 1; -1 1], 'valid'); % partial on x
% Iy_m = conv2(im1, [-1 -1; 1 1], 'valid'); % partial on y
% It_m = conv2(im1, ones(2), 'valid') + conv2(im2, -ones(2), 'valid'); % partial on t
u = zeros(size(im1));
v = zeros(size(im2));

% within window ww * ww
for i = w+1:size(Ix_m,1)-w
   for j = w+1:size(Ix_m,2)-w
      Ix = Ix_m(i-w:i+w, j-w:j+w);
      Iy = Iy_m(i-w:i+w, j-w:j+w);
      It = It_m(i-w:i+w, j-w:j+w);

      Ix = Ix(:);
      Iy = Iy(:);
      b = -It(:); % get b here

      A = [Ix Iy]; % get A here
      nu = pinv(A)*b; % get velocity here

      u(i,j)=nu(1);
      v(i,j)=nu(2);
   end;
end;

% downsize u and v
u_deci = u(1:10:end, 1:10:end);
v_deci = v(1:10:end, 1:10:end);
% get coordinate for u and v in the original frame
[m, n] = size(im1t);
[X,Y] = meshgrid(1:n, 1:m);
X_deci = X(1:20:end, 1:20:end);
Y_deci = Y(1:20:end, 1:20:end);
figure();
imshow(img2);
hold on;
% draw the velocity vectors
quiver(X_deci, Y_deci, u_deci,v_deci, 'y')

end

入力と出力結果

左2つが入力で出力が右のようになります。
f:id:ossyaritoori:20161007224346p:plain

MATLABのグラフから動画を作る

聞かれたので昼休みに作ったまでです。

MATLABでたくさんFigureを出した時に比較する手段として動画にするというのはよくあると思われます。

本プログラムのステップは

  • 描画
  • getframeによる取得
  • Videowriterによる書き込み

の3ステップになっています。

コード

どうぞご自由に。コードでは2次系の粘性項を変えた場合のステップ応答を作成していますね。

%% make movie from MATLAB plot
clear all;
close all;

Frate = 5;
k = 0:0.1:3;
for i = 1:size(k,2)
    % First, make figure
    sys = tf([1],[1 k(i) 1]);
    figure(1);
    step(sys);
    xlim([0 10]); ylim([0 2]);
    grid on;
    
    % Put current figure into Frame
    Frame(i) = getframe(1);
end

% % convert the Frame to movie and show
% figure(2);
% movie(Frame,1);

% write to video
v = VideoWriter('step.avi');
v.FrameRate = Frate; % Framerate

open(v);
writeVideo(v,Frame);
close(v);

Amazon Fire(Kindle Fire)タブにGooglePlayストアをダウンロード(LINEをダウンロード)

節子「お兄ちゃん,このタブレット安くてお得だね。」
f:id:ossyaritoori:20161004010339p:plain:w300
兄「節子それAndroidやない!Playストアがないんや~~!!!」
f:id:ossyaritoori:20161004143703p:plain

茶番はさておき,今回は,前回の記事で買った
AmazonFireタブにLINE等のアプリを入れたい方のための記事です。

0.準備物と流れ

大雑把に流れは,
1. PCに幾つかソフトをインストール
2. Fireタブを接続して操作
という感じになっており,

  • 快適に動作するPC
  • PCとの接続用のUSBケーブル

の2つをご用意ください。2つ目のケーブルは買ったときにもついてきますが,某所で【読み込まれない】との噂を聞いたので
私は別にケーブルを用意しました。

基本は以下の記事に準拠して環境構築を行っていきます。
Amazon Fireタブレット(第5世代/2015年モデル)にGoogle Playストア をインストールする方法 & インストールしたアプリの検証 | mogi2fruitsどっとねっと



1.PCにADB(Android開発者用)をインストール

Androidの開発者権限を用いてゴニョゴニョするため,
開発者用のソフトウェアをインストールする必要があります。

次のサイトに行って,DownloadsからADBのzipファイルをダウンロードしてください。
forum.xda-developers.com

インストーラーを起動すると以下の画面が出ます。
f:id:ossyaritoori:20161004172024p:plain
全ての項目にYesと答えてインストールを完了させてください。

2.GooglePlayストアをインストールするツールをダウンロード

以下のサイトに行くとGooglePlayストアをインストールするツールをダウンロードできます。
rootjunkysdl.com

トップから[Amazon Fire 5th Gen]を選択します。
2016年10月では5世代目ですが,世代が進んだら別のファイルを選択する必要があるかもしれません。
f:id:ossyaritoori:20161004172641p:plain:w400

そうすると以下のページにたどり着きますので,
rootjunkysdl.com
Amazon-Fire-5th-Gen-Install-Play-Store.zip」を選択してダウンロード,解凍してください。

3. Fireタブの設定で「USBデバッグ(ADB)」を有効にする

Fireタブの
[ 設定 ] → [ 端末オプション ] → [ シリアル番号 ] を7回連続でTapしてください。
【 開発者オプション 】というのが表示されると思います。

借り物の画像ですがこんな感じになります。
f:id:ossyaritoori:20161004173154p:plain:w350


その後,
デバッグ 】の下にある 【 ADBを有効にする 】をONにします。
オレンジ色になったらON状態です。

4. PCとタブレットを接続。インストーラーの起動。

さて,ようやく大詰めです。タブレットとPCとをケーブルで接続します。

手順1:タブレット側からPCからの操作を許可する

接続するとタブレット側にて「 USBデバッグを許可しますか? 」との表示がされるはずで,
ここで「常に許可」とすることを忘れないでください。

人によってはこの画面がなかなか出ないこともあって(私がそう)その場合,手順2をやってから手順1を行ってもいいです。
恐らくその時点ではうまく行ってないので手順1の後もう一度手順2をやると思います。

手順2: 先程ダウンロードしたツールを使う

2.ダウンロード,解凍したフォルダに行き,「1-Install-Play-Store.bat」 というファイルをダブルクリックで起動してください。

こんな画面が出ます。

ちなみに,これは手順1がうまく行かなかった時にとったのでFireの状態が "unauthorized" になっていますね。
この部分がきちんと認識された表記になっていれば問題なく進むと思われます。
f:id:ossyaritoori:20161004174501p:plain

次にしばらくして,このような画面が出るでしょう。
f:id:ossyaritoori:20161004174755p:plain
数字の「2」を押して次に進みます。

いろいろ途中経過の画面が出てきて,最後に
f:id:ossyaritoori:20161004174858p:plain
と出ます。

Fireタブを確認してGooglePlayストアがインストールされていれば完了です。

最後に: 再起動

参照したサイトにはなかったのですが,僕の場合おかしな挙動になったので,
一度再起動したら問題なく進めました。
恐らく,インストールした後は一度再起動をすると無難かと思われます。

以後は普通にGooglePlayストアが入るので,LINEなりなんなり入れ放題ですが,
未だ対応しきれいていないソフトもあるそうです。



これでFireタブをAndoroidタブレットとして使う事ができました。
おすすめソフトなどは気分がのれば書きます~。では。

Amazon Fire タブは買いか?

突然ですが携帯が壊れて泣きそうです。
新しく買うにはiPhoneシリーズは高いし,
中古を吟味せずに買うのは少しばかり不安です。

そんな時amazonで見つけたこのタブレット
https://www.amazon.co.jp/dp/B00Y3TMKKM/ref=twister_B01A07WSOS?_encoding=UTF8&psc=1www.amazon.co.jp

f:id:ossyaritoori:20161004010339p:plain
プライム会員の割引でなんと5000円で買えちゃいます。

5000円と安い!Fireタブは果たして買いか?

結論ですが私は手持ちのタブが欲しかったので買ってしまいました。
何も調べずに買ったので買ってから知らなかった!となった点を連ねていきます。

実際良かった点

安さの割にスペックがそこそこ

予め8Gの容量があり,メモリもそこそこあるので
最新機種とは比べられませんが,単なるタブレットとしては十分使える性能です。

付属品のクオリティもまずまず

包装はあってなきがごとしですが,USBアダプタとケーブルが付属します。
どちらもそこそこ品質は良さそうです。
ただし,今度別記事にする【開発者権限での作業時にこのケーブルは向かない】ようです。

注意すべき点(本題)

最大の良さは安さみたいなところがあるので早速本題に入ります。

OSがAndroidではない

もっと簡単に言うと,LINEなどの一部の有名?アプリに対応していないんです。
どうもAmazon用にカスタマイズされているらしく,じょうよわ的にはこれらの機能が使えません。

ちょっとパソコン使えるぞ!という方は次に記事にするゴニョゴニョでこの問題がいくらか解決します。
ossyaritoori.hatenablog.com


とにかく,何も考えないでこれを買うと,手に入れたいアプリが入らないという問題があるわけです。
これが最大の注意点だと思います。

wifiが地味にシングルバンド(5GHz帯のwifiを使えない)

簡単に言うと使えるwifiの種類が他機種より若干減ります。
環境によっては致命的なのできちんとwifiの周波数を確認しておくのを強くおすすめします。


あと地味に初期設定時にWPA-EnterPrizeに繋げない。
つまるところUtroamやEduroamなどの学内LANにアクセスできないのがネックです。
【後で設定】を押すと回避できるらしいので,一応なんとかなるらしいです。

初期設定後はきちんとつなげているのでちょっとした誤差ではありますが。

正直あとは値段相応

大きさはiPhone5を3つ横に並べた程度のもので,表面がやたら指紋が付きやすいとかいろいろ考えたんですけどやっぱりその他は値段相応な気がします。




結論

ブラウジングや動画鑑賞専用としてか,
多少PCいじれて高望みしないならば十分に買い

Windows.hでファイル選択ダイアログ作成

どうもご無沙汰してます。
私事ですが最近アメリカに旅行にいって最高でした。
身バレしない程度に写真や出来事上げて自慢したいっす。はい。


では本題。

GUIでファイル選択ダイアログ作りたい

自作プログラムで参照するファイルをいちいち変更したり,引数として事前に与えるのが面倒なので
ファイル選択のGUIを実行時に出して選択できると非常に捗るかと思います。

今回作るものはこんなやつです。
f:id:ossyaritoori:20160926162829p:plain

意外と分量があるので関数として追加する時は
新たにファイルを作成しちゃってもいいと思います。

重要な部分

ウィンドウズ環境では Windows.h をインクルードして,
GetOpenFileName()という関数を呼ぶだけで済みます。

ところがどっこい,これに与えるファイルの作り方などがよくわからず,
結局ネットで例文を調べる羽目になることかと思います。

ひっかかった所

  • TCHAR が Unicode環境下でcharと扱いが異なる。

この関数ではPath名とファイル名を保存する型にTCHARを用いています。
マルチバイト文字を容認するUNUCODE環境下ではこれはcharと扱いが異なるので
そこらへんの区別をするところでもう一手間使わされました。


コード

gist使うべきか迷いましたがまぁ普通に貼るだけでいいでしょう。
はてなブログ以外のサービスを利用するべきな気がしてきた。

#include "Windows.h"

// 二度目呼び出すと最初のやつは消えます。注意してね。
char *GetNameFileOpen()
{
	HWND hWnd = NULL;
	static OPENFILENAME     ofn;
	static TCHAR            szPath[MAX_PATH];	// 初期フォルダ位置
	static TCHAR            szFile[MAX_PATH];   // 選択したファイル名 Staticなので関数外でも生きているが,もっかい呼ぶと死ぬ。
	static char				szFname[MAX_PATH];  // 出力用のファイル名 charの方が扱いやすいことがある

	if (szPath[0] == TEXT('\0')){
		GetCurrentDirectory(MAX_PATH, szPath);
	}
	if (ofn.lStructSize == 0){
		ofn.lStructSize = sizeof(OPENFILENAME);
		ofn.hwndOwner = hWnd;
		ofn.lpstrInitialDir = szPath;       // 初期フォルダ位置
		ofn.lpstrFile = szFile;       // 選択ファイル格納
		ofn.nMaxFile = MAX_PATH;
		ofn.lpstrFilter =
			TEXT("すべてのファイル(*.*)\0*.*\0");
		ofn.lpstrTitle = TEXT("ファイルを選択します。");
		ofn.Flags = OFN_FILEMUSTEXIST;
	}
	if (GetOpenFileName(&ofn)){
		MessageBox(hWnd, szFile, TEXT("ファイルを開く"), MB_OK);
	}
	else{
		// cancelled
		return "saved_image.bmp" ;
	}

	//ここからcharへと変換する
#ifdef UNICODE
	{
		int		nLen;

		//charに必要な文字数の取得
		nLen = ::WideCharToMultiByte(CP_THREAD_ACP, 0, szFile, -1, NULL, 0, NULL, NULL);
		if (szFname)
		{
			//変換
			nLen = ::WideCharToMultiByte(CP_THREAD_ACP, 0, szFile, (int)::wcslen(szFile) + 1, szFname, nLen, NULL, NULL);
			if (nLen == 0)
			{
				//error
				*szFname = NULL;
			}
		}
	}
#else
	{
		size_t	nLen;

		nLen = ::_tcslen(pszTchar) + 1;
		pszChar = new char[nLen];
		if (pszChar)
			::strcpy_s(pszChar, nLen * sizeof(char), pszTchar);
	}
#endif

	return szFname;
}

Raspberry Pi 3 を買ってみた -セットアップ編-

前回のこの記事の続きです。
ossyaritoori.hatenablog.com

少しPCの知識があるのが前提ですが(コマンドがわかる,打てる程度)
Raspberry Piを買う人は大体意欲か経験を十分に備えているのできっと大丈夫でしょう。

セットアップの前に

セットアップの前に以下のものがきちんと揃っていることを確認しましょう。

この辺は言わずもがな

  • HDMIケーブル
  • ディスプレイ

ケーブルはできるだけ短く抵抗値の低いものを。
ディスプレイには相性があるようです。

  • USBマウス,キーボード
  • 無線LAN端子
  • 適切なソフトを入れたMicroSDカード
  • SDカードに書き込みが出来るPC

これについて次に説明します。

ステップ1:MicroSDに必要なデータを入れる

最初のステップとして,MicroSDに必要なデータ(OS等)を入れます。
これには様々な手法があるのですが私は以下のサイトを参考にセットアップを行いました。
karaage.hatenadiary.jp

1-1 Raspbian Jessie をダウンロード

以下のサイトからRaspberry Piに入れるOSとなるraspbianをダウンロードしてください。
www.raspberrypi.org

1GB以上あるので電波状況の良い所でやると良いです。

1-2 データを展開,windowsからSDカードに書き込み

ダウンロードしたファイルを適当なところに展開し,SDカードに書き込みます。
Linuxならddコマンドで,Macなら先ほどのサイトを見てください。

Windowsを使っている場合はやや面倒で,私はDDforWindowsというソフトを使いました。

Index of /dd_for_windows
上の場所にアクセスして一番下の最新のファイルをダウンロード,解凍してください。

次に,管理者権限として実行すると
f:id:ossyaritoori:20160821194215p:plain
このような画面が出るので,
「ディスク選択」→ 挿入したSDカードを選択
「ファイル選択」→ 展開したraspbianを選択

してMicroSDカードに書き込んでください。

ステップ2:Raspberry Piの本体を起動

電源以外の全てのケーブル類を接続し,SDカードを差し込んでから
電源ケーブルを差し込みます。電源のONOFFは存在せず,電源を刺した瞬間がONになります。

つらつらと長いコマンドが一通り流れた後,スタート画面に移行します。
2016年5月のVerではIDとPASSは入力しませんでしたが,

初期ID:pi
初期Pass:raspberry

であることに注意してください。

はい,ここまで来ると今回の記事は殆ど終わりです。
残りは日本語環境を整えるという内容になります。

ステップ3:日本語環境のセットアップ

ここまで書いておいてなんですが,
これ以降は
karaage.hatenadiary.jp
さんの記事が絵付きで非常にわかりやすいのでそちらを参照したほうが良いかもしれません。

3-1 言語,地域設定

「Menu」 → 「Preferences」→ 「Raspberry pi configuration」
から言語設定と,地域設定を行います。

ここで再起動すると文字化けして読めなくて詰むのできちんと上の参考文献の通りにやることをおすすめします。

3-2 日本語変換関係のファイルのダウンロード

恐らくフォント情報等をダウンロードする工程です。これも参考文献と全く同じです。

$ sudo apt-get update
$ sudo apt-get install fonts-vlgothic
$ sudo apt-get install ibus-mozc

この後,一度再起動をします。

次に「menu] → 「設定」→ 「iBusの設定」
から入力メソッド の追加を行い,日本語入力を追加します。
画像無いのでやはり上の文献を見てね。

おまけ:アップデートの確認

一応アップデートがないか以下のコマンドで確かめることが出来ます。

$ sudo apt-get update
$ sudo apt-get upgrade

お疲れ様でした。(主に参考文献を書いた方)

ユーザー名の変更の必要性

ここからはAdvancedな内容になります。
実はラズパイの初期ユーザーpiとデフォルトパスワードのままにしておくと外部から簡単にアクセスされてしまう問題があります。
そこで幾つか設定する必要があります。

おいおい記事にしようと思うので今は以下のリンクを貼るだけにしておきます。
jyn.jp


wifiへの接続の備考

utroam,eduroamなどIDとパスワードで認証を行うタイプの回線につなぐには過去記事を参照してください。
ossyaritoori.hatenablog.com

Raspberry Pi をutroamにつなぐ (WPA2-EnterprizeのIDとpassを必要とするwifiネットワークにつなぐ)

セットアップの記事の途中ですが
覚えてるウチにメモしておきます。

問題

Raspberry Pi 3はデフォルトでwifi接続が可能となっていますが,
utroamのようなidとpassが要求されるネットワークには接続できません。
(少なくとも私のraspbianの環境では)2016/8/20現在

WPA2-Enterprizeについて

タイトルの通り,ユーザごとにアカウントとパスワードを設定して認証を行うタイプのことのようです。
この他にWPA2-Personalという物があり,こちらは事前に設定した鍵に基づいて認証を行うタイプで,モバイルルータの裏面のキーフレーズを入力するといったよくあるタイプです。

解決編

3ステップで解決していきます。

ネットワークインターフェイス の変更

/etc/network/interfacesのファイルを編集します。
当然スーパーユーザーで行ってください。

$ sudo emacs /etc/network/interfaces

参考文献3 にならって以下の様に変更を加えてください
iface eth0 inet manual
↓変更
iface eth0 inet dhcp

(以下は不要ですが念のため)
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
↓変更
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
追加
iface default inet dhcp

ipアドレスdhcpで探してくれるようにするということみたいです。

configの編集

つぎに,/etc/wpa_supplicant/wpa_supplicant.confを編集します。
同様に好きなエディタで開いてください。
参考文献1のようになかを編集します。

以下のような文を追加してください。

アクセスポイント名は今回はutroam-1xになります。

network={

    ssid="アクセスポイント名"

    identity="ユーザ名"

    password="パスワード"

    key_mgmt=WPA-EAP

    eap=PEAP

    scan_ssid=1

}

接続

設定を反映するために一度wifi接続を再起動します。

$ sudo ifdown wlan0
$ sudo ifup wlan0

参考文献1によると以下のような応答が出るはずです。

Copyright 2004-2011 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/b0:c7:45:a9:91:9c
Sending on LPF/wlan0/b0:c7:45:a9:91:9c
Sending on Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 3
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 8
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 16
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 192.168.143.1
DHCPACK from 192.168.143.1
bound to 192.168.143.236 -- renewal in 1433 seconds.


これでwifiへの接続が完了しました。

問題追記 2016/8/21

この後に電源を切って再起動した所
eth0もwlan0もどこにも繋げない現象を一度だけ確認しました。
学校の回線が死んだだけ説もありますが一応可能性として追記しておきます。

無線ネットワークにつなぐと
有線ネットワークの扱いはどうなるのか,
有線と無線をうまく使い分けることは可能なのかが今後の課題です。

追記2017/3/25

wpa_supplicantの書き方ですが参考文献4に非常にシンプルな例を見つけましたので追加します。
今のところ普通につなげています。
key_mgmtEAPを指定しているのがよくわからないですがとりあえずうまくいくようです。