工作室」サイトの日記的なブログです。サイトに挙げなかった他愛ないことを日記的に書き残してます。工作室」topに戻ります。arduino別館」topに戻ります。PythonPython3、tkinter、Pillow使って年末からゴニョゴニョとやっていた、画像処理するGUIツールのメインロジックがようやく動くようになった。何をやってるのかを簡単に纏めなおすと、ブギーボードみたいなやつをaliexで買って、メモとか計算とかで結構便利に使えていい買い物だったんだけど、保存機能が根本的に欠落しているのをナントカしたい、と。液晶を利用しているデバイスなんだけど、デジタル機器ではないので、直接PCと接続したりして、画像(や文字)を保存しておくことができない。デジカメとかで撮影して、それをPCに残しておくくらいしかないんだけど、書いた(描いた)ものはそのままではちょっとみづらい。二値化して見やすく加工してから残しておきい。この液晶のコントラストが結構低いので、レタッチソフトとかで単純な二値化をすると、まともに図柄を抽出できなくて、それなりの画像処理が必要になってしまうというもの。この課題をクリアしたいと。実験用の画像サンプルとして使っているのが、これ。右上はライトが当たっていて明るい一方、左下はライトが暗くて図柄の線も微か。人の目には、これでもちゃんと「図」と「地」の違いが見分けられるんだけど、CPU君はこれをどうやったら上手い事区別できるのか。試行錯誤した結果、とりあえず力技のロジックでこないだやってみたのがこれ。元画像から、結構くっきり抽出できていると思うんだけど、問題はこれ1枚(640×480ほど)を処理するのに2〜3分かかっちゃう。そんな遅いとまともに使えない。計算処理をもうちょっと工夫して、実用に耐える速度を出そうというのが、ここのところの課題だったわけ。あれこれ考えながらロジックを弄りなおしていたんだけど、ようやく一通りまとまって、実行できる状態になったので、動かしてみた。出てきた画像が、まずこれ。なんだこれ?バグった。pdb使って計算途中の変数をながめてみる...計算結果をストックしている変数に、まともに値が入ってない(というか、全部ゼロ)というのがあって、どうやら、初期化する関数を呼び出してなかったみたいな。そのあたりをゴニョゴニョなおす。こんな風になっちゃった...なんだろう?と思って、pdbで途中で止めて、ワーク変数の中身をダンプ。ドットの輝度の平均値を計算しているところで、平均値がマイナスになってしまっているところがある。光が吸収されてしまっている。オイラはうっかりブラックホールを作り出してしまったようだ。地上にブラックホールはまずいので、事故が起きないうちにこっそりバグを直す。こんな具合に、抽出できた。さっきの長時間かかるロジックの結果と比べて、微小な部分でドット単位の差異はあるんだけど、見てのとおり、ほぼ同じ結果が得られた。ちなみに処理時間は、全体で約10秒くらい。予定通り2桁ほど速くはなったんだけど、なんでこの程度の処理が秒単位で掛かっちゃうんだろうなぁ?そんなに重い処理では無いんだけどな...と思って、考え直す。処理ロジック自体は相当まともなんだけど、よく考えてみたら、これを動かしているVirtualBox上のLubuntuって、仮想環境だから処理能力が低いんだよな...と。以前、仮想環境の処理能力をUnixBench掛けてみた結果を見直してみる。Piくらいの能力しかないことがわかる。Note(CF-T9)のネイティブ環境で実行してみた結果は、これよりも1桁速い値が出てきてた。NoteのCPUをPassMarkで見てみると、https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core2+Duo+U9600+%40+1.60GHz&id=10201000ちょっとで、UnixBenchと同じくらいの数値になってる。PassMarkはCPU単体のベンチで、UnixBenchはディスクI/Oとか色々なものまで含めたベンチなので、一概に比較は出来ないものの、大体同じくらいの指標と仮定してみる。今回使った仮想環境と、メインで使ってるPCの処理能力とで比較すると、およそ30倍くらいの処理能力差がありそう。ことで、仮想環境で10秒くらい掛かるなら、メインPC使えば0.3秒で終わるんじゃないかな?と。実際はそこまで速くはならないだろうけど、1秒は掛からないだろう。このロジックのまま、Androidに移植しても、1秒前後で処理が完了するんじゃないかな。あと、もっとデカい画像で処理しても、実用時間内で処理が完了できるだろうと。仮実装になってる部分とか、GUI操作の使い勝手とか、その辺を改めて実装していこう。出来ればtkinterでタブ表示したいよなぁ、とか思ってちょっと調べてみた。https://qiita.com/yusk24/items/3af56d0599be200559dehttps://torina.top/detail/413/https://qiita.com/fiftystorm36/items/96014a13b09777925055どうやら、tkinterのnotebookっていうウィジェット?(コンテナ?)を使うか、力技で押し込むか、どっちかってことになりそうかな。ちなみに、画像処理のロジック内容の作戦はこう。あるドットの周囲の平均値を求めておいて、その値とそのドットの輝度を比較して、明るければ「図」、暗ければ「地」として把握しようっていう作戦。単純にそういう処理をすると、たとえば以前も触れたこんな画像の場合、こんな風に、暗い部分については微小なノイズを拾ってどうでもいい模様を拾い上げてしまう。「地」の部分の場合は、その地の明るさを加味させて、要らない模様を抽出しないようにする必要が。それと、逆に、塗りつぶししたところは、周囲も明るいので、こんな風に塗られていないものとして扱われてしまう。こんなふうに、四角に塗りつぶした内側が黒くなってしまう。四角く塗りつぶしたところも、ちゃんと塗りつぶされているように、ちゃんと補正するロジックが考慮されてはいる。(いろんな条件で撮影された写真でもちゃんと動作するように、固定値とかマジックナンバーとかで処理しないように工夫している)あとは精度だな。実用範囲で妥協しつつ、できればこれ以外の画像にも適用できるようにしたいところ。https://twitter.com/ryogomatsumaru/status/1082258614008537088面積の問題。