読者です 読者をやめる 読者になる 読者になる

nvidiaドライバを入れたubuntuにVNC接続する際に一部のプログラムが起動しない(segmentation fault)場合の解決策

概要

タイトルのとおり、nvidiaドライバを入れたubuntuサーバーに対して、VNC接続をすると、一部のプログラムが起動しない問題が発生したので、原因とその解決方法を記載する。

環境

Ubuntu16.04(サーバー側)
vncにてmateのdesktop環境を使用しログイン
chainerを実行するため、nvidiaドライバ、cuda等をインストール済み

t-nkb.hatenablog.com

状況

vncリモートログイン環境において、firefoxは起動しないけれど、chromeは起動する。
iBusも起動しないため、日本語入力もできない・・・・という変な状況。

解決方法

このサイトの解決方法が役に立った。
VNC Segmentation Fault on Ubuntu 16.04/Linux Mint 18 - Imaging and a little bit of OSS

私の場合は以下の通りのコマンドを打つことで解決した。
上記サイトにも記載があるが、/usr/lib/直下のnvidia***フォルダを見て、nvidia-375..以降を適宜変更する必要がある模様。

sudo ln -s /usr/lib/nvidia-375/libGLX_nvidia.so.375.39 /usr/lib/x86_64-linux-gnu/libGLX_indirect.so.0

ubuntu16.04でkubuntuをインストールしようとするとエラーが出る→その後の対処法

kubuntuの導入失敗

unityから脱却しようかと思い、ubuntu16.04にkubuntuを入れようとしてみた。
ネットで調べると、

$ sudo apt-get install kubuntu-desktop

とすれば一発でインストールできるとの事だったので実行してみると途中までうまく行き・・・・
configureing gdmという画面でデフォルトのgdmを選べと言われるので、gdm3を選択。
その後再びインストール画面が続き、うまく行くかと思いきや、途中で致命的なエラーが出てインストールが終了!!!
おいおいこれ大丈夫か??と再起動してみると案の定、デスクトップ画面に行く前にフリーズしてしまい、GUIは全く使えない状態に・・・・。

まずはkubuntuを消す

まずはkubuntuを消そうと思い、外部からSSHでログインし、aptコマンドを実行すると、これすら

The following packages have unmet dependencies:
 kde-telepathy-minimal : Depends: kde-config-telepathy-accounts (>= 15.04.0) but it is not going to be installed
E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).

とエラーが出てしまい実行できず。
言われたとおりに、

$ sudo apt-get dist-upgrade -f

を実行してみても解決されず、
おいおいマジかよ・・・。

落ち着いて海外のフォーラムで事例を探すと、同様の事例で困っている人がいたので、これを頼りにdebファイルを上書きしてから、再度dist-upgradeすることで、とりあえずエラーは解決。

#解決した対処方法
$ sudo dpkg -i --force-overwrite  /var/cache/apt/archives/kde-config-telepathy-accounts_4%3a15.12.3-0ubuntu1_amd64.deb
$ sudo apt-get dist-upgrade -f

(参考)
askubuntu.com

次にデフォルトで起動するデスクトップをunityに戻す

kubuntuは諦めて、とりあえず現状復帰を目指します・・・・。
念の為、

$ service --status-all

として、gdm3のサービスが[+](起動中)となっていて、lightdmのサービスが[-](停止中)となっていることを確認する。
なるほど、これを逆にすればいいわけね・・・。ということで、以下のコマンドで元に戻す。

sudo dpkg-reconfigure lightdm #gdmの切り替え
sudo reboot #再起動

あとは再起動後、serviceを確認し、gdm3のサービスが[-](停止中)となっていて、lightdmのサービスが[+](起動中)となっていればOK、無事GUIログインできるはず!


・・・あぁ、ちょっと試してみようと思ったら思わぬ時間の浪費をしてしまった。

cv2で動画読み込み時にerror: (-215) size.width>0 && size.height>0というエラーが出る場合の対処法(Windows)

概要

ネット上でよく見るWindowsへのcv2導入方法に従ってcv2を導入すると、動画読み込み時(cv2.videoCapture()使用時)に"error: (-215) size.width>0 && size.height>0"というエラーが出てくる。
これはffmpegのDLLがないため、動画が開けずに出てくるエラーだが、一見すると何を言っているのかわからない点が厄介。
このエラーにしばらく苦しんだので、解決方法を記しておく。

解決方法

よくあるWindowsへのcv2導入方法を見ると、

1.OpenCV2.4.1等をダウンロード
2.C:/opencv/build/python/2.7/x64の cv2.pydをC:/Python27/lib/site-packegesにコピー
(anacondaで導入している場合はC:/anaconda/lib/python27/site-packages等)

と、ここまでしか手順が書いていない場合がある。

確かにこれでもcv2がインポートできて使用できるのだが、掲題のエラーが出て動画読み込み時にエラーになってしまう。
これでは片手落ちだ・・・ということで、以下の通りffmpegのdllをコピーしてあげる。

3.opencv/build内にあるopencv_ffmpeg310.dllも一緒に2のフォルダにコピー

これで正常にファイルが読み込めるようになるはず。
opencv_ffmpeg310.dllが見つからない場合は、適当にドライブ内を検索してやればOK。

sshfs中に通信が切れた場合の対処法

sshfsの問題点

機械学習を行う際、基本的に自宅サーバーのフォルダをsshfsでマウントして、作業を行っている。

t-nkb.hatenablog.com


しかし、アンマウントを忘れて通信を切断、スリープしてしまうとマウントポイントが残ったままとなり、以降このディレクトリにアクセスできなくなる。
当然、この状態になると、再度sshfsでマウントしようとしても以下のエラーが出て、マウントできない。

例えばmacだとこんな感じでエラーが出る。

mount_osxfuse: mount point (マウント先リンク) is itself on a OSXFUSE volume
fuse: failed to mount file system: Invalid argument

解決策(接続時に自動で強制アンマウントさせる)

そこで、エラーが出たマウント先を強制的にアンマウントし、再度接続してあげる。

umount -f (マウント先ディレクトリ)

以下のようにエイリアス作っちゃうと便利。

alias sshfs2="umount -f (マウント先ディレックトリ);(マウント元アドレス):(マウント元ディレクトリ) (マウント先ディレクトリ)"

linux screen中にマウスホイールでスクロールする方法

sshが切れても学習が継続できるよう、最近はscreenを使って学習をすすめることが多い。
携帯からでも気軽に途中経過見えるし。
しかし、screenの画面はスクロール等が実行できず、過去のログを閲覧することができない。

t-nkb.hatenablog.com

困って検索したところ、以下のように設定を変更することで、マウスホイールで過去ログが見られるようになった。
これは便利!

$ sudo emacs ~/.screenrc

以下を追記(最初は新規作成)
ついでにスクロールバッファ行も増やしておく。

termcapinfo xterm* ti@:te@
defscrollback 100000

screenを再起動
screenが初期化されるので、作業中の場合注意。

$ reset

再開時は画面に表示されている分しか履歴が表示されず、スクロールしても過去ログの部分は空白になってしまうため、都度以下を行う必要がある。
これで読み込んでしまえば、読み込んだ部分は編集モードに遷移しなくとも参照可能。

・一旦、ctrl + a,escとして編集画面に遷移
・⬆️ボタン長押しで過去のログを読み込み
・escキーを押して元のモードに遷移

cv2(openCV)で動画の途中から再生する方法

概要

openCVで動画の任意の地点から再生を開始する方法をまとめる。
これまではwhileループで1フレームずつ取得し読み飛ばしていた。しかし、この方法はあまりにも無駄が多い・・・時間もかかるし、HDDにも悪影響が出そう。
ということで、もう少し効率の良い方法を調べてみた。

従来方法

飛ばしたい時間分フレームを読みこませるだけ、簡単だけど、100秒のスキップに10秒ほど時間がかかる。
流石にこれじゃねぇ・・・。ということで、次の手法。

movie = cv2.VideoCapture(input_filename)
if movie.isOpened() == True:
    ret,frame = movie.read()
else:
    ret = False


# フレームを連続で読み込ませる
for i in range(framerate*shift_time):
    ret,frame = movie.read()

高速手法

開始のゼロ点をms単位でセットしてあげるだけ。スキップはほぼ一瞬。
HDDへのアクセスも少なく、パソコンに優しい!

movie = cv2.VideoCapture(input_filename)
if movie.isOpened() == True:
    ret,frame = movie.read()
else:
    ret = False

#スタート地点をsetする
movie.set(0,shift_time*1000)
ret,frame = movie.read()

疑問点

h264動画を取得すると、以下のエラーが出る。
キーフレームが見つからないってことなんだろうけど・・・・。
このエラーが出てもとりあえず読み込めてるから、とりあえず用は足りる。
(キーフレームが出るまで再読込してるのかな??本当はopenCVのソース読んで確認すべき。)

[h264 @ 0x2f1fac0] Missing reference picture, default is 0
[h264 @ 0x2f1fac0] decode_slice_header error

pythonでgooglemap情報を扱う方法まとめ

概要

googlemapデータを機械学習の元ネタにするために、データの取り扱い方を調べたのでまとめておく。

地名から座標(緯度経度)、詳細住所を取得する

pipでインストール

pip install pygeocoder


あとはpythonで書くだけ。

from pygeocoder import Geocoder
address = '国会議事堂'
results = Geocoder.geocode(address)
print(results[0].coordinates)
# => (35.675888, 139.744858)

result = Geocoder.reverse_geocode(*results.coordinates, language="ja")
print result
# => 日本, 〒100-0014 東京都千代田区永田町1丁目7−1 国会議事堂

ふむ、簡単にかける割にはすごい。

特定の座標周辺の地図を画像として保存

次は、上記で得た座標を元に周辺の地図画像をダウンロードしてみる。
基本的には以下URLを参考にした。

Google Static Maps API入門
Google Mapの地図の画像を取得するには – 山本隆の開発日誌

pipでライブラリをインストール

sudo pip install urllib

以下のように、地図画像を取得して保存させる。
自分で書いておいてなんだけど、いまいち美しくない…。

from pygeocoder import Geocoder
import urllib

def download_pic(url,filename):
	img = urllib.urlopen(url)
	localfile = open( "./" + str(filename) + ".png" , 'wb')
	localfile.write(img.read())
	img.close()
	localfile.close()

address = 'ホワイトハウス'
results = Geocoder.geocode(address)
print(results[0].coordinates)

result = Geocoder.reverse_geocode(*results.coordinates, language="ja")
print result

html1 = "https://maps.googleapis.com/maps/api/staticmap?center="
html2 = "&maptype=hybrid&size=640x480&sensor=false&zoom=18&markers="
html3 = "&key=googleから取得したキーコードを入力"

axis = str((results[0].coordinates)[0]) + "," + str((results[0].coordinates)[1])

html = html1 + axis + html2 + axis + html3

print html

download_pic(html,address)

f:id:t_nkb:20161221131234p:plain

ちゃんとホワイトハウス周辺の地図が保存できた。さすがグーグル、使いやすくできてる。
細かなパラメータについては上記リンクを参照。