
そして彼らは言った:あなたはボタンを押し、数字を見て、パスワードを入力して喜ぶ。 「もちろん、セキュリティは最優先事項ですが、快適さを忘れてはいけません」と私はそれについて考え、私の電子機器を修正しました。
(正直なところ、私は長い間プログラミングから気をそらし、ハードウェアを深く掘り下げたいと思っていたので、この怠慢はこの仕事全体の唯一の動機ではありません)。
技術仕様の分析とコンポーネントの選択
最初に目を引いたのは、古いLogitech QuickCam 3000 Webカメラで、Webカメラを内蔵したラップトップの購入に関連してゴミになりました。 計画はすぐに熟しました。カメラでトークンから数字を削除し、コンピューターでそれらを認識し、...利益を上げます! その後、サーボドライブが見つかりました(まあ、毎回トークンのボタンを手で押してはいけませんか?)、古いUSBハブ(私のラップトップにはUSBポートが2つしかなく、そのうちの1つはUSB-Ethernetアダプターで常に占有されています)、およびArduinoボード、どうやって終わったのかはわかりません。 私のデバイスのケースとして、私は1歳の息子が将来のために購入したレゴコンストラクターを使用することにしました(購入時に妻が悪意を持って笑った理由がわかりました)。
残念ながら、安全で健全なドナーデバイスの写真はありません。そのため、デバイス全体について「自慢する」ことしかできません。

マイクロコントローラーの概略図とファームウェア
実際、すべてがとてつもなくシンプルです(図を描画しません)。WebカメラとArduinが接続されたUSBハブです。 サーボドライブはArduinoに(PWMを介して)接続されます。 arduinoに流し込まれるプログラムのソースコードは簡単です: github.com/dreadatour/lazy/blob/master/servo.ino
Arduinaはcomポートで「G」の文字を待っており、到着するとサーボを前後に引きます。 サーボの遅延(500ms)と傾斜角は実験的に選択されました。
プログラミング言語の選択と「コンピュータービジョン」の既存ライブラリの分析
「コンピュータービジョン」のような難しいタスクを任せるのは、祝福されたPythonだけです。 幸いなことに 、 OpenCVのようなすばらしいライブラリーには、すぐに使えるバインダーが実際にあります。 実際、これでやめます。
トークンコード認識アルゴリズム
説明した機能に関与するコードへのリンクを提供します-私の意見では、これは情報を提示するための最適な形式です。 すべてのコードはgithubで表示できます。
開始するには、 カメラから画像を取得します 。

カメラはベースに対して静止しているため、トークンはトレイ内で非常にわずかに移動できるため、トークンの可能な位置の境界を見つけ、カメラからフレームを切り取り、(便宜上) 画像を 90° 回転させます 。

次に、変換を行います 。結果の画像をグレースケールに変換し、Canny境界検出器を使用して境界を見つけます。これらは、トークンLCDスクリーンの境界になります。

結果の画像で輪郭を見つけます。 輪郭は線の配列です-特定の長さ未満の線を破棄します:

愚かなアルゴリズムを使用して、LCDディスプレイを制限する4行を決定します。

これらの線の交点を見つけて、いくつかのチェックを実行します。
- 垂直線と水平線の長さが互いにほぼ一致し、線の長さがLCDのサイズとほぼ一致することを確認します(実験的に計算しました)
- 対角線がほぼ等しいことを確認します(長方形が必要です-LCD)
次に、トークンが回転する角度を見つけ、この角度で画像を回転し、LCD画像を切り取ります。

最も難しい部分は後ろにあります。 次に、結果の画像のコントラストを上げる必要があります。 これを行うには、空白のLCD画面の画像を記憶し (トークンボタンを押す前)、数字を含む画像からこのボタンを「 減算 」します(ボタンを押した後)。

白黒の画像が得られます。 これを行うには、別の愚かなアルゴリズムを使用して、画像内のすべてのピクセルを「黒」と「白」に分割し、画像をB / Wに変換して文字を切り取る最適なしきい値を見つけます。

それでは、数字を認識するだけです。 ニューラルネットワークなどに苦しむことは意味がありません。 7セグメントインジケーターがあります。各桁を一意に決定する 7つの「ポイント」があります。

念のため、いくつかのフレームから数字を認識します。3フレーム連続で同じ結果が得られた場合、認識に成功したと思われるため、「growlnotify」プログラムを使用して結果をユーザーに表示し、結果のコードをクリップボードにコピーします。
デバイス作業ビデオ
注意、音!
ソースコード全体