俺言語。

自分にしか理解できない言語で書かれた備忘録

【MATLAB】設定ファイルの保存場所

PC入れ替えなどで前の環境(文字色,背景色など)を新しい環境に引き継ぎたい場合,

下記に設定ファイルがあるのでそれを新しい環境へコピーする。


Location: C:\Users\(user_name)\AppData\Roaming\MathWorks\MATLAB\(version)
File: matlab.prf

https://jp.mathworks.com/help/matlab/matlab_env/preferences.html#buhx0ov-10



環境設定は何度かクラッシュしたことがあるのでこのファイルのバックアップを

とっておくとよいかも。

【Python】グラフの外にテキスト表示 or 対数グラフ内の右隅にテキスト表示

グラフの外にグラフ情報を表示したい場合,

または対数グラフ上にテキストを表示したい場合の方法。

対数グラフ内にテキストを表示する場合,axes.text()では位置合わせが難しい。

そういう場合はfig内での座標でテキスト表示するのが有効。


テキストの位置はグラフに対する相対的な位置指定をしたい場合が多いと思うので

fig内のaxesの位置をax.get_position()で取得すると良い。

# fig内でのaxes座標を取得,戻り値はBbox
ax_pos = ax.get_position()

# fig内座標でテキストを表示 Bboxは Bbox.x0, Bbox.x1, Bbox.y0, Bbox.y1で座標を取得できる
fig.text(ax_pos.x1 - 0.1, ax_pos.y1 - 0.05, "string")

【Python】numpy2次元配列でキーを使ったソートの方法

エクセルの並び替えの様に優先するキー(軸)を指定した並び替えが少しめんどくさい。
なぜそれ用の関数orオプションがないのだろうか…。

方法としては

  1. キーにする軸のみargsortでソート後のインデックスを取り出す
  2. そのインデックスを使ってソートする前の配列から新しい配列を作る
  3. np.c_で配列を結合


具体的な方法は

import numpy as np

# 100x2の配列を作成
a = np.random.rand(100,2) 

# キー軸をソートした後のインデックスを取り出す
ind = np.argsort(a[:,0])

# ソート後のインデックスで元の配列を並び替え
new_a0 = a[ind, 0]
new_a1 = a[ind, 1]

# 配列を結合
new_aa = np.c_[new_a0, new_a1]

実際は全て一行にまとめて

new_aa = np.r_[a[np.argsort(a[:, 0]), 0], a[np.argsort(a[:, 0]), 1]]

って書いたりする。

【Python】GetWindowTextで取得できない文字列を取得する方法(win32api SendMessage WM_GETTEXT)

GetWindowTextで文字列が取得できない場合(他プロセスのコントロール文字列は取得できないらしい、意味不明)は

指定のハンドルにメッセージを投げて文字列を取得する。

投げるメッセージの定数はwinuser32.h内に記載されている。

ハンドルはspy++等で調べることが可能,16進数の整数。

SendMessageは末尾に"A"(ANSI版)と"W"(unicode版)どちらかが選択できるが

日本語で帰ってくる可能性があるはずなので"W"にしてみている。今のところ問題はなし。

import ctypes

def get_control_text():
     # ハンドル
     hwnd = 0x0001096C

     # 定数はwinuser.hに定義されている
     msg_gettextlength = 0x000E
     msg_gettext = 0x000D

     # 受け取るテキストの文字長さを取得(wParam,lParamは0にすること) 終端文字列は含まず
     len_str = ctypes.windll.user32.SendMessageW(hwnd, msg_gettextlength, 0, 0 )

     # 文字列バッファを定義
     buff = ctypes.create_unicode_buffer(len_str + 1)

     # 文字列を取得 第3引数にwParamに文字数,第4引数にlParamに文字列バッファ
     ctypes.windll.user32.SendMessageW(hwnd, msg_gettext, len_str +1, buff )

【Python】ウィンドウのタイトル文字列を取得する方法(win32api user32 GetWindowText)

win32apiのGetWindowTextを使ってウィンドウの文字列を取得する方法 <流れ>

1.EnumWindowsでトップレベル(アクティブという意味ではない)のウィンドウハンドルを取得
 EnumWindowsは引数にコールバック関数が必要なのでコールバック関数を定義


2.GetWindowTextLengthでタイトル長を取得(タイトル長は終端文字を含まない点に注意)


3.タイトル名を格納するバッファをctypes.create_unicode_bufferで用意 バッファ長は終端文字を含むため
 GetWindowTextLength +1にすること


4.GetWindowTextでタイトルを取得
 引数は(ウィンドハンドル,文字列用バッファのポインタ,文字列長)

import ctypes

def get_window_title():

    """
    ctypes.WINFUNCTYPE(戻り値の型, コールバック関数が想定する引数の型)
        : windowsのコールバック関数を定義 定義するだけなので引数は具体的なインスタンスではなく型を指定するのがミソ?

    user32.EnumWindows: トップレベルウィンドウのハンドルを順番にコールバック関数へ送る

    user32.IsWindowVisible(hwnd): 可視化されたウィンドウであればTrueを返す

    user32.GetWindowTextLengthW(hwnd):ウィンドウハンドルのテキスト長を返す

    ctypes.create_unicode_buffer(長さ): 変更可能な文字列?を作成 型は文字列配列になる 意味的には w_char*10と同じ,違いが良くわからん

    user32.GetWindowTextW(hwnd, 文字列格納用バッファ, 文字列長さ)

    ctypes.POINTER():引数型のポインタを作成
    ctypes.pointer():引数のポインタを返す
    """


    # コールバック関数を定義(定義のみで実行ではない) コールバック関数はctypes.WINFUNCTYPEで作成可能
    EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
    # ??
    EnumWindows = ctypes.windll.user32.EnumWindows
    # タイトル格納用変数
    title = []

    def foreach_window(hwnd, lparam):
        if ctypes.windll.user32.IsWindowVisible(hwnd):
            length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
            buff = ctypes.create_unicode_buffer(length +1)
            ctypes.windll.user32.GetWindowTextW(hwnd, buff, length + 1)
            title.append(buff.value)

            return True

    EnumWindows(EnumWindowsProc(foreach_window), 0)

    print title

↓参考にしたサイト
sjohannes.wordpress.com

【Python】str.isdigitsは小数を判定できない罠

文字列が数値かどうか判定するstr.isdigits

"."が含まれていると数値として判定してくれない。

str.isdigits("123") 
>> True

str.isdigits("12.3")
>> False

回避方法としては簡単なものはreplaceメソッドで"."を""に置換してしまうこと。

str.isdigits("12.3".replace(".",""))
>> True

但しこれは厳密にいうと数字でない".123"や"..123"もTrueが返ってきてしまうので要注意。

この場合は正規表現を使ってやる必要があるみたい。

↓参考になったサイト
d.hatena.ne.jp

【Python】openCVのcv2.imshow()でエラー error: (-215) size.width>0 && size.height>0 in function cv::imshow

動画を読み込んで表示するプログラムでエラーが発生。

import cv2

src_m = cv2.VideoCapture("ファイル名")

r, f = src_m.read() #←1フレーム読み込み
cv2.imshow('title', f) #←フレーム表示

aviファイルはエラーが出ずに表示できるものとできない物があった。
エラーが出なかったものも画像が斜めに変形して表示されおかしい状態。
mp4, tsは読み込み出来ずだった。

エラーメッセージは

error: ..\..\..\..\opencv\modules\highgui\src\window.cpp:261: error: (-215) size.width>0 && size.height>0 in function cv::imshow

原因は"import cv2"でインポートされるモジュール cv2.pyd が

何故かc:\Python\DLLs 内に単独であって

本来インポートされるべき

C:\Python27\Lib\site-packages 内の cv2.pyd が読み込まれていなかった。

たぶんインポートの順番かPYTHONPATHの記述の順番のせいか?


これはcv2をインストールし直した時のバージョンと

インポートして cv2.__version__ で確認したバージョンが一致しなかったことから判明。


このエラーは cv2.pyd と同じディレクトリにopencv_ffmpegという恐らく

デコード担当のファイルがない時に出るらしく今回はまさにそれだったと思われる。


opencv_ffmpegが同じディレクトリに必要というのは下記にあった。
stackoverflow.com