MVTecADのデータをPyTorchから利用するためのデータセットクラスを開発した

MVTecADという製品検査における異常検知用のデータが公開されている。

それほど扱うのが難しいデータではないが、かといってデータセットクラスの実装にはそれなりに時間がかかる。
ということでこのデータを扱うためのPyTorchのDatasetクラスを開発して公開することにした。
github.com


誰かの役に立てば幸いである。

Mean-shit法による画像のセグメンテーションについて勉強

Mean-shit法による画像のセグメンテーションについて勉強

以下のMean-shiftの解説資料で勉強をおこなった。
ミーンシフトの原理と応用 , 岡田和典, 平成21年
 
Mean-shiftはどんな手法か?
→ ゆえに一般的に部分領域の数が事前にわからず、部分領域の形状が様々な画像のセグメンテーションに向いている。
→ 画像処理でもカーネル幅で結果が変わる。カーネル幅が小さいとたくさんの部分領域が生まれる
 
代表的な画像処理への応用は以下
  • 画像のセグメンテーションと平滑化
  • 同画像におけるトラッキング
OpenCVにおける画像のセグメンテーションと平滑化は、解像度を落とした画像の処理から始め、徐々に解像度をあげることで計算量を減らしているそうだ。
実装はかなり単純なようだ。大学生のプログラミングの演習課題になっていそう。
 
以上。
 
 
 

複数画像の位置合わせによって白飛びを緩和する方法の検討

概要

光沢のある物体を撮影すると、光の反射によって一部の領域が白潰れしてしまうことがある。
撮影位置をずらしたり様々な対処法はあるが、ここでは微妙に撮影角度を変えて撮影した複数画像を使って対処する方法を考えたので共有したい。

まず扱う問題は以下のような白潰れである。

f:id:KYudy:20201123190648j:plain
白潰れが起きている画像の例

このように白飛びが起きていると、例えば画像からテキストが正しく読み取れなくなる。
試しにGCPOCRにかけてみるとこうなる

f:id:KYudy:20201123190944p:plain
GCPOCRのテキスト読み取り結果

CORONAのOが読み取れていないことがわかる。

手法の詳細

考案した手法の発想は微妙に角度をずらしながら撮影すれば照明が反射する場所を少しずつ変えることができ、それらの画像を平均することで白潰れを緩和できるのではないかというものだ。
ただし、角度を変えながら撮影すると画像上の対象物の位置が変わってしまうため単純に画像の画素の平均は意味をなさない。
そのために画像の位置合わせを行うことでこれに対処する。

画像の位置合わせの手法は以下を大いに参考にさせていただいた。
qiita.com

さて全体のアルゴリズムを図示するとこのようになる。

f:id:KYudy:20201123191808p:plain
手法の概要図
  • 1ステップ目では複数枚撮った写真の中で一つを参照画像(Reference Image)とし、それ以外の画像をReference Imageに対して位置合わせする。
  • 2ステップ目であh位置合わせされたすべての画像の画素値の平均をとりそれを出力とする。

非常に単純である。

ためしに先程のCORONAのストーブを撮影した下記の動画からフレームを抽出しこの手法を適用してみよう。
youtu.be

以下がその結果である。人目にCORONAがはっきり読み取れることがわかる。

f:id:KYudy:20201123193327j:plain
考案した手法の適用結果

次に適用前と比較する目的でGCPOCRにこれをかけてみる。

f:id:KYudy:20201123193433p:plain
GCP OCRの適用結果(考案手法適用後)

今度は正しくCORONAを読み取ることができた。
単純な手法だが、有効であることがわかった。

ソースコードGithubに掲載した。
github.com

セイコー ダイバーズの修理(2)

前回で修理は完了したはずだったが、夜に時計を見て夜光塗料が光っていないのに気づいた。経年劣化だろう。
大した支障があるわけではないが気になるので夜光塗料を塗ってみた。

購入品

以下を購入した。夜光塗料は色々あるみたいだが、安価であり、かつアマゾンのレビューで時計修理に使用されていることがわかったのが決め手である。
Amazon.co.jp: カンペハピオ(Kanpe Hapio) 工作・ホビー用水性塗料 なし 8ML 夜光クリーム: DIY・工具・ガーデン

・光を3~5分当てることで、暗闇で15分程度発光します。

15分くらい光るなら自転車で会社から帰るときも光り続けてくれる。

修理の手順

分解

以下の手順で行う。
1. 前回同様に3点支持のオープナーを使って裏蓋を開ける。
2. 竜頭を外す
3. 時計の中身(基盤と文字版など)を引っ張り出す

1.は前回の記事と同様に行った。
2.は以下の画像に図示した箇所を爪楊枝で押しながら竜頭の取り外す
3.は時計の中身(?)を普通に爪で引っ掛けて引っ張り出す

f:id:KYudy:20200811230331p:plain
竜頭を外すために押下する箇所の図示

塗装

爪楊枝の先端に少し塗料をつけて細かく塗装する。
塗料は水性なのではみ出たりしたときには剥がすことができる。
分針の塗装が非常に難しかった。縁の銀色の箇所には塗らないようにしながら白色の箇所に塗布するのだが、とにかくはみ出る。
はみ出たら爪楊枝で細かく剥がすが、剥がしすぎるとやり直しになる、ということの繰り返しだった。

f:id:KYudy:20200811230728j:plain
塗装中の様子

実験

なんとか及第点の塗装ができたので、試しに暗い部屋で光り方を確認した。
思ったより良く光る。これはいい。

f:id:KYudy:20200811231419j:plain
光り方確認

最後に

分解作業は難しくはないが、塗装がとにかく精度が求められて難しいということがわかった。正直あまり満足の行く結果は得られないことがわかった。よほど手先が器用でなければきれいに塗装することはできない。

セイコー ダイバーズの修理

実家に帰ったら父が昔着けていた時計(セイコーのダイバーズ)が放置されていた。
ゴム製のバンドがボロボロになり、電池が切れ、ペプシ柄のベゼルも傷と色あせでどうもあまり見栄えしない感じになっていた。
高級時計ではないが安い時計でもない。そこで引き取って修理することにした。

時計の修理は初めてだったが、やや苦労はありつつも問題なく修理ができた。
ここでは修理のために買ったもの、手順などを紹介したいと思う。

購入品

合計4,750円の出費となった。

ベゼルインサート単体をメルカリで購入した。正直これほど安く売っているものだとは思わなかった。ベゼルインサートのサイズはノギスで外周の直径(38cm)と内周(31.6)の直径を測定して同じサイズのものを検索して見つけた。ネットで探すと色や柄は各種あるようだったが、落ち着きを重視して黒の単色のものを選んだ。

f:id:KYudy:20200730234849j:plainf:id:KYudy:20200730234852j:plain

電池はコンビニで探したが売ってなかった。そして検索すると時計用電池は専門店でしか売ってないようだったのでヨドバシで購入した。

f:id:KYudy:20200730235315j:plain
取り外した乾電池

バンドは無難に純正を選んだ。

修理用の工具はAmazonで適当なものを購入した。レビュー通り品質は良くないが、素人が自分の時計の修理に使う分には必要十分であった。

修理の手順

ベゼル交換

先が刃物のように鋭い道具を本体とベゼルの隙間に差し込んでテコの要領で力をかけてベゼルを外す。更にベゼルのインサートを下側から押しあげるようにして外す。(力をかけすぎるとインサートが曲がるので注意が必要。)
インサートが外れたら交換用のインサートを上から押し込む。押し込んだだけでは入り切らなないためハンマーのプラのヘッドのほうで軽く叩いてはめた。

f:id:KYudy:20200730234855j:plainf:id:KYudy:20200730234840j:plain
ベゼル取り外し、インサート交換

バンド交換

古いバンドを時計から抜き取るために、バネ棒はずしを使った。
思っていたよりもバネ棒が固かったため取るのに苦労した。バネ棒外しがなかったら多分外せなかっただろうと思う。
古いバンドを取り外すよりも新しいバンドを取り付けるのは簡単だった。

電池交換

3点支持のオープナーを使って裏蓋を開ける。この3点支持オープナーの品質が悪く、ガタツキがあるため力をうまく伝えることができなかった。結局取り外すために10分以上必要だった。

f:id:KYudy:20200731001824j:plainf:id:KYudy:20200731002028j:plain
裏蓋と3点支持オープナー

裏蓋が取れると電池が見えるのだが、その上に電極と電池の固定を兼ねたパーツが覆っている。非常に小さなネジでそれは固定されているのだが、修理工具に入っていたマイナスドライバの先が厚く、そのままではネジ頭の溝に入らなかった。そこでドライバの先を包丁研ぎで数回研磨して溝に入るようにした。
しかし、ここで悲劇が起きる。この電極パーツが少しバネのようになっていて、それに気づかずドライバを回してネジを取ろうとした瞬間にネジが飛んでどっかに行ってしまったのだ。
頭が真っ白になりそうだったが、頑張って手探りで探したらなんとか見つけることができ事なきを得た。本当によかった。
最後に逆の手順で新しい電池に入れ替えたところで時計の針が動き始めた。

まとめ

時計の簡単な修理についてまとめた。
素人でもある程度の修理であればできることがわかった。

f:id:KYudy:20200731004933p:plain
修理後

Snakeによる輪郭抽出を実装してみた

以下の本を読み始めた。 opluse.shop-pro.jp 第一章の動的輪郭モデルに関する話の冒頭で代表的な方法であるSnakeがでてきた。 アルゴリズムの説明があり、シンプルだったので自分で実装してみた。

こんな感じで動いた。

f:id:KYudy:20200531103535g:plain
m570の動的輪郭追跡(gamma=0.7)

gammaを0.7から0.5に変えると以下のようになった。画像の勾配に対して鈍感になるのでM570の左上のクリックボタンの輪郭を取れなくなってしまった。 一方で画像の勾配に鈍感な分、輪郭を縮めるので収束が速い。

f:id:KYudy:20200531101326g:plain
m570の動的輪郭追跡

ソースは以下のgistに載せた。 skimageをインポートしているが、Snakeのメインのアルゴリズムは自分で書いている。 Pythonでループを使って書かれているのでとても動作が遅いがアルゴリズムを理解するために書いたのであまり気にしていない。 Snakeのアルゴリズムはいくつかあるが、上記の書籍で紹介されているアルゴリズムは以下である。 Donna J et al. A Fast algorithm for active contours and curvature estimation. gist.github.com

GCPのdebianにsshするときにXの転送が失敗する場合の対処

GCPを使っているときにX転送して、画像をsxivで開いて確認したりしたくなることがある。 debianインスタンスでsxivを実行しようとしたら、以下のようなエラーが出た。

@localhost
$ ssh -Y gcphost
@gcphost
$ sxiv ...
sxiv: Error opening X display

よく見返すとsshの直後に以下のようなエラーも出ていた。

X11 forwarding request failed on channel 0

こういうときに役に立つのが、StackOverflowである。 https://stackoverflow.com/questions/38961495/x11-forwarding-request-failed-on-channel-0

以下の順番で設定していったが、結局xauthをインストールした後に直った。

  • /etc/ssh/sshd_configにX11Forwarding yesを追記
  • /etc/ssh/sshd_configにX11UseLocalhost noを追記
  • sudo apt install xauth