avis_courrier: 営業戦士の諸兄諸姉、書類届いてます通知箱があるので今夜も安心して直帰できますよ


Abstract

こんな感じで書類を入れて

フタを閉じて、スイッチを押すと

中のカメラがこんな感じで撮影して

こんな感じに台形補正して

メールで通知してくれます

請求書とか契約書とか、帰社して処理しておかないとお客様が怒りだしそうな書類さえなければ、今日もお客様と飲みにいっても大丈夫! というか、そういう書類だったとしても的確な指示をだして飲みにいってください
会社の売上はすべて営業の努力のおかげと日々感謝をしております
次の商談の獲得のためにぜひ、今夜も営業戦士として立派に戦ってきてください!

ドキュメント、ソースコード一式等はこちらにございますので、お気に召していただけましたらスターつけていただければ嬉しいです
clone していただけるだけでも正直うれしいです

解決しようとする課題

課題の生じた現場の特性

職場を流行りのフリー・アドレスにしたら営業の重鎮たちが直行直帰の繰り返しで全然会社に来なくなってしまい、まあ営業が元気に飛び回ってるのは健全なことなのでいいのですが、営業ゾーンの共用書類箱に誰も触ってない書類が山積みなのは大丈夫なのか?

という問題意識をもたれた某社の偉い人から、なんとかしてよドラえもん的な依頼をいただきましたのがちょうど一年前の今頃でございました、もうちょっと寒かったかな

立派な複合機のある立派な会社なので、それをつかって届いた書類を PDF にしてメールで通知すればよさそうなのですが、めんどくさいので誰もやってくれないのだそうです
自分の為のめんどくさい事でさえ基本嫌がるものなのに、まして同僚のための面倒くさい事ってそりゃみんな嫌がるでしょうね

web アプリの提案と、それでも残った課題

ようするに、届いた書類を手近の人が複合機まで持っていってスキャンをするのが嫌だ、ということなら自席で自分のスマフォでできれば解決するのではないか、と考え
急いでつくって提案したのがこの web アプリ biff です
処理フローはこんな感じで

Web アプリだとアプリのダウンロードが不要なので拒絶反応が小さくなります
biff の URL にアクセスするとこんなかんじでドキュメントの写真撮影が促されて

撮影して biff サーバに送信すると、通知先選択画面になるので

通知先ボタンをクリックすると配達通知メールがきます
コードはこちらです

配達通知だから biff というネーミングセンスが UNIX 世代のジジ臭さが見え隠れして恥ずかしい次第です

しばらくこれで使っていただいていたんですが、まだめんどくさくてみんなに使ってもらうには至らないとの事でした

解決策:書類箱に Raspberry Pi で送信機能をもたせる

届いた書類を各ゾーンの書類箱に入れてくれるところまでは今でもやってくれているそうなので、そのタイミングで自動的に撮影して送信するしかなさそうです
書類箱が1人に1箱だと、開閉センサーでフタの操作を検知すればよさそうだし、数人で共用の書類箱だと通知先分のスイッチを用意すればよさそうです、ボタンを一回押すだけぐらいだったらさすがに御協力のお願いもできそうです

こうして、冒頭の通知箱 avis_courrierが誕生しました
ネーミングもフランス語っぽくてオサレです

システム構成はこんなかんじで、既存の biff にまぜちゃいました

Raspberry Pi は、世間の普通の人が見ると怖がるらしいので箱の側面に目立たないように隠してあります
こういうノウハウはIT系じゃない人とコラボしないとなかなかわかりません

avis_courrierを可能にした部材

3V 1W 120°ワイド LED

この LED です

Raspberry Pi の GPIO に直接つないで点けたり消したりしたかったので、3Vの LED 探してて、これを見つけました
冒頭の写真みたいに並行線につけて、反対側は dupont 端子をかしめつけて GPIO につなぎます
GPIO の 16mA のドライブ電流でどのぐらい明るく光ってくれるのか不安だったのですが(3V1W のLEDですから、1/10以下の電流ですよね)予想外に明るく、逆に電流が少ないので触っても温かいとも感じないぐらい発熱がすくなく、普段大容量の LED を使っていて LED というと発熱を心配される人達にも好評でした
このLEDの照明で冒頭の写真がとれています

LED の on/off 制御は、平行線の一方をGNDにつないで、もう一方をGPIO(たとえば36番)につないでこんな感じで OFFに落としておいて

# Camera light setting
GPIO.setup(36, GPIO.OUT)
GPIO.output(36, GPIO.LOW) # keep tune off without taking photo

撮影時だけこんな感じでONに上げます

command_str = os.path.dirname(os.path.abspath(__file__))+'/photographier.sh '+filename+'.tmp'+' '+device+' '+size
GPIO.output(36, GPIO.HIGH) # 撮影のために点灯
p = subprocess.check_call(command_str, shell=True)
GPIO.output(36, GPIO.LOW)  # 撮影後は消灯 

薄膜パネルスイッチ [HC-54342]

これがスグレモノで、こういうキーパッドみたいなのはほとんどが GND,信号,Vin の3線式になっていて、キー毎に値の違う抵抗が入っていて、信号の出力を AD コンバーターで読め、というのがほとんどで、BeagleBone と違って AD コンバーターのない Raspberry Pi だとひと手間電子工作が必要になってしまうのですが、こちらはなんと、4つのスイッチで5線式! つまり、スイッチを押すと各pin が最後の線と接続するというなんともデジタルな、まさに Raspberry Pi で使うためにあるような便利なスイッチなので、たとえば最後の線を GND につないでおいて、他の線を各々 GPIO につないで pull up して falling を待てば(もちろん、逆でもいいです)こんな感じでスイッチの押下を検知できます

       for spec in specs: 
         if GPIO.event_detected(spec["pin"]): 
           logging.info("detect " + str(spec["pin"])) 

BUFFALO 広角120° WebCam BSW200MBK

今回、最大の功労者というか、この WebCam の存在をしらなかったら多分、「無理でした」ってギブアップしてたと思います

5cm 程度の高さから、普通の WebCam でA4の書類全体を俯瞰するのっていろいろ試したのですが無理なんですよね
2台のカメラで撮影した2枚の映像を、台形補正した上で合成する方法を探してたのですが、ふと BSW200MBK ならななんとかならないかと思ってためしてみたところ、冒頭の写真のとおりボケボケとはいえ、一応俯瞰できてるじゃないですか!凄い

この値段で 120°の視野角という、左右それぞれ30°しか死角のないカメラはほかに知りません
eBay で 120° angle を歌う安い WebCam がいくつもありますが、これ以外に試したものは全て「偽」でした...

Raspberry Pi を使った静止画ベースの見守りシステムMONITOR™ で、ミャンマーの小規模発電プラントの稼働状況を日本から見守った際に、普通の WebCAM に安い広角アダプターをつけて撮影していた画像がこれだったのですが

これを同じ取り付け位置で BSW200MBK に変えるとこうも変わりました

これが 120°の威力です!すごいですね
これがなかったら本当に avis_courrier は生まれていませんでした
こんな素晴らしいWebCamを30$以下の値段で買える日本に生まれてきて本当によかったと思います(海外でこれを買おうとするとどうしても50$以上してしまいます)

avis_courrierを可能にしたソフトウェア技術

たいしたことなにもしてないです ^^;;;

台形補正

強いて言えば台形補正で、こんな条件でどうやって補正値だすためのエッジ検出したらいいんだろ?大きな書類の上の小さな書類だとどっちのエッジかどうやって識別したらいいか?などウジウジと30分ほど悩んだのですが、冷静に考えたら歪みが毎回同じなんだからエッジ検出なんかしなくても固定値で補正すればいいんですよね、おマヌさんでした ^^;;;

台形補正は OpenCV の warpPerspective で こんな感じでやってます

def transform(ifile,ofile,left,right,depth):
    img = cv2.imread(ifile,1)
    rows,cols,ch = img.shape

    print rows
    print cols

    pts1 = np.float32([[0,0],[rows,0],[-left,cols],[rows + right,cols]])
    pts2 = np.float32([[0,0],[rows,0],[0,cols - depth],[rows,cols - depth]])

    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst = cv2.warpPerspective(img,M,(cols,rows))

    cv2.imwrite(ofile,dst)

SDカードのセキュリティ

昨日ご説明いたしました通り、暗号化ストレージとコピープロテクション(コピーしたSDカードだと起動しない)で保護しています
これやっとかないと怖くて世にだせないので ^^;

avis_courrier の現状と今後

結局、こんなのがあればとおっしゃられてた方が異動になり、そのまま私も疎遠になって使って頂く事もかなわず現在に至っております

どこにもヒモがついていない状態でお蔵入りしてるのですが、せっかく作ったのに使わないのはもったいない話なので、もしどなたか

  • 同じようなの作ってみたい
  • ちょっと見てみたい、使ってみたい
  • うちの営業も元気すぎて会社に寄り付かないので無理にでも使わせたい

など、ご興味をお持ちの方がございましたら前述の通りコードは全部オープン(実際のメールアドレスを登録する部分とかはテンプレートだけ公開してます)なのでご自由にご利用いただければ幸いです。もし、気に入っていただければスターを頂ければ大変ありがたいです

作ったり使ったりした上でなにか問題がございましたらご遠慮なく本稿へのコメントや、おのおの biffavis_courrier のリポジトリで issue を上げていただければ至福の至りです
ご奇譚のないご意見を頂ければ大変参考になりありがたい次第でございます

また「文字列と写真じゃイメージが沸かないのでちょっとデモして欲しい」とか、「細かいこといろいろ聞きたい」とか「ランチ一緒にいかがですか」とか「一度飲みに行かない?」などのご相談やご提案もご遠慮なくこちらまで頂きましたら喜んでご対応させていただきますのでよろしくお願いいたします次第でございます

感想

はじめて Raspberry Pi Advent に参加させていただきまして感無量です!

実は 2015年に Raspberry Pi Advent を立てた張本人なのですが、ボーっとしてたら速攻で全日埋まってしまい、立てた本人がなにも書かない立て逃げみたいなおマヌな事をヤッてしまったことが今日までトラウマになっておりました ^^;;;
以来、2016年、2017年とやっぱり参加できず、やっと3年越しで初めて参加させていただきますことが叶い、今は痛い冠がとれた草冠の姫みたいなとても穏やかな気分です