iPad 9.7 用にpencilケースを100円(格安)で自作する方法
また箸休めですが、今回は最近買ったiPad 9.7 (2018)とApple pencilの為に、100円程でpencilホルダーを作成しました。(ついにこのブログで縫い物を紹介するとは思いませんでした)
最初に断っておくと、私はApple信者ではないので、デザイン性より利便性、カスタマイズ性、重量を重視しております。
なので、「せっかく廉価モデルのiPad 9.7 2018買って費用安く抑えたのに、ケースやらなんやらで4〜5000円とか払うのなんてやだよ!」って人にはオススメです。
別にすごいことはなく誰でも思い付くアイディアではあります。
必要なスキルは、「縫い物ができること」のみです。
(縫い物できなくてもいいですね、そうミシンがあればね)
完成画像
まず完成形はこちら。
iPad、iPadのケースに巻きつけるようなゴムバンドケースを作成しました。
ケースに取り付けるとこんな感じ。
割とサラサラとしたゴムバンドなので上から左にスライドすると、
下から「ぴょこん」と出てくる。(これがかなり便利)
すっ、、、ぴょこん!
作り方
作り方のまとめはこちら。
※慣れの為に、図や絵はApple Pencilで書いてます。(割と書ける)
雑だけどこれが全てである。
大雑把に言うと、20mmゴムバンドを一周半して重なる部分をコの字に縫い付けるだけでできる。
必要な材料と道具
材料
- 20mmゴムバンド (税別100円)
- 刺繍糸
- ボンド
- 爪楊枝 (option)
道具
- 定規
- ハサミ
- 刺繍針
- 待ち針 (option)
手順
スーパーシンプルな3ステップです。
1. 測って
まずゴムバンドを635 [mm] 切り出す (幅はそのまま 20 [mm])
【重要】切り出した両端はボンドをつけて乾かす
解れ防止です。
放置、もしくは、ドライヤーで乾かすとあらキレイ。
2. 折り曲げて
横から見た図は実際にはこんな感じ。(オーバーラップは145 [mm] あればOK)
マチ針か仮縫いで留めておく
3. 縫って(終了)
オーバーラップ部分をコの字に縫い付けていく
(私は左下から縫っていく)
一応、縫う所のイメージ(赤線を上下で繋げる)
縫い付けは端から 2 [mm] ぐらいだといい感じにペンをホールドしてくれる
途中経過はこんな具合
【重要】コの字出口は5 [mm]ほど残しておく(反対側からの写真)
これを残しておくと、スライドした時にここがストッパーになるし、差し込む時の目印にもなるので便利
あとは無心で縫って完成
所感
- ペンケースの保持力もOK(逆さにしても落ちる気がしない)
- スライド感もOK
- めちゃくちゃ便利
- 2週間程使っているが、全く壊れそうにない
ペンキャップ Ver.も作ったがそれも便利だった。
Julia言語とは(備忘録 : 更新版)
twitterなどで目にする機会が増えて、昨日初めてJuliaチュートリアルに参加したので備忘録。(更新版)
チュートリアルで頂いたステッカー↓↓
可愛いね。
Juliaについて
Juliaのライセンス
MITベース
ただし中にあるプロジェクト単位で様々なライセンスがぶら下がっている模様
商用利用はお気をつけて。
julia/LICENSE.md at master · JuliaLang/julia · GitHub
Juliaは何故早い
細かいことはよくわかりませんが、わかっていることだけで
簡単に始める方法
- Juliabox https://juliabox.com/
IDE環境
- Juno IDE http://junolab.org/
- Atomへの導入
margaret-sdpara.blogspot.jp
atom.io
-
- Visual Studio CodeのJuliaの拡張機能
パッケージ
https://pkg.julialang.org/
2018/3/24時点で1749パッケージが登録されている
個人的に、Mamba.jl , BackpropNeuralNet.jlに興味がある
github.com
github.com
他の言語を実行可能
Julia上でgccやclangが実行できるため、C, Fortranのコードを実行可能
Calling C and Fortran Code · The Julia Language
Juliaboxのチュートリアルにもある
Cxx.jiで対話実行できるのでこっちも。
github.com
【python】OCR(tesseract-ocr / pyocr)で賞味期限を読み取る(画像→数列) 【お家IT#19】
本件の実装の一部
motojapan.hateblo.jp
前回の続き
motojapan.hateblo.jp
目次
前回は、バーコード画像から商品情報を取得するところまで進めた。
ただ、商品情報には賞味期限情報は含まれていない。
今回は、OCRを用いて賞味期限を数値、記号情報として取得する。
OCRとは
Optical Character Recognition 光学的文字認識を指す。
紙面に書かれている文字情報を認識してデジタル化する技術であり、書籍や資料を電子化することでデータ圧縮や管理の容易化ができるだけでなく、ソフトウェアと連携してデータ分析なども可能となる。
今回は賞味期限を読み取りたい。
特に、stand-aloneで利用できるtesseract-ocrをpyocrから触ってみる。
(その他のライブラリは次回)
tesseract-ocr / pyocrとは
tesseract-ocrは、OCRエンジンである。
最新α版は、4.00.00alpha。
4系からは、OCR Engine Modeで、LSTMが選択できるようになっている。
(ただし、下記pyocrからは、Mode設定がサポートされていない模様で、LSTMは今回は試せなった)※2017/10時点
github.com
pyocrは、tesseract-ocrをpythonから操作する為のWrapperである。
かなり感単に操作が可能となっている。
インストール
tesseract-ocrをインストール & チェック
#install $ sudo apt-get install tesseract-ocr #check $ tesseract -v tesseract 3.03 leptonica-1.71 libgif 4.1.6(?) : libjpeg 6b : libpng 1.2.50 : libtiff 4.0.3 : zlib 1.2.8 : libwebp 0.4.1 : libopenjp2 2.1.0
pyocrをインストール & チェック
#install $ pip install pyocr #check $ python >>> import pyocr >>> pyocr.get_available_tools() [<module 'pyocr.tesseract' from '/usr/local/lib/python2.7/dist-packages/pyocr/tesseract.pyc'>]
使い方と実装
pyocr.builders
pyocr.buildersには次の5つの使えそうなBuilderがある。
TextBuilder | 文字列を認識 | |
WordBoxBuilder | 単語単位で文字認識 + BoundingBox | |
LineBoxBuilder | 行単位で文字認識 + BoundingBox | |
DigitBuilder | 数字 / 記号を認識 | 今回はこれを採用 |
DigitLineBoxBuilder | 数字 / 記号を認識 + BoundingBox |
今回は、撮影枠を準備しているので、DigitBuilderを採用。
tesseract_layout (pagesegmode)
tesseract_layoutを設定しているが、ここは次のpagesegmodeの番号と対応している。
ここの設定でかなり精度は変わる。
デフォルト設定は、tesseract_layout=3。
今回は、tesseract_layout=6で、単一ブロックとして認識。
OSDとは、On Screen Display? サブタイトルなどの認識に利用するらしい。
pagesegmode values are: 0 = Orientation and script detection (OSD) only. 1 = Automatic page segmentation with OSD. 2 = Automatic page segmentation, but no OSD, or OCR 3 = Fully automatic page segmentation, but no OSD. (Default) 4 = Assume a single column of text of variable sizes. 5 = Assume a single uniform block of vertically aligned text. 6 = Assume a single uniform block of text. 7 = Treat the image as a single text line. 8 = Treat the image as a single word. 9 = Treat the image as a single word in a circle. 10 = Treat the image as a single character.
実装
import time import pyocr from PIL import Image import pyocr.builders #img : PIL image def get_digit_ocr_info(img): result = None start_time = time.time() print('******** start convert_image_to_deadline *********') width, height=img.size tools = pyocr.get_available_tools() tool = tools[0] print(tool) langs = tool.get_available_languages() print("support langs: %s" % ", ".join(langs)) #lang = langs[0] lang = 'eng' #言語設定で、「英語」を選択 digit_txt = tool.image_to_string( img, lang=lang, builder=pyocr.builders.DigitBuilder(tesseract_layout=6) ) print('DigitBuilder', digit_txt) print('******** end convert_image_to_deadline *********') return digit_txt
結果
色々なパターンを12件ほど評価。
入力画像 |
tesseract+pyocr |
2018. 6.12 |
|
18.12.31 |
|
2018. 5. 7 |
|
18.09.14 |
|
18.03.28 |
|
4 13 11-13 . . 3 |
|
2017.12 31 |
|
4 21 3 |
|
13. 1-7 |
|
17.12.22 |
|
20-178.... 3 13 |
|
2311 8.13 |
200 x 60 の画像に対して、処理速度は、2 - 3 [s]程度。結構時間がかかる。
上手くいくものもあれば、厳しいものもある。
特に、太い文字、判で刻印されたシャープな数字はかなりいい感じだが、無駄な文字が含まれている画像、暗い画像、ドット記載されている数字が上手く読み取れていない印象。
以上。
これでシステム全体の開発は終わり。
また何か作る予定です。
今回触れなかった他のOCRライブラリの話もそのうち纏めたい。
【python】Yahoo Web APIでバーコード情報(JAN)から商品名を読み出す(数列→商品情報) 【お家IT#18】
本件の実装の一部
motojapan.hateblo.jp
前回の続き
motojapan.hateblo.jp
目次
前回は画像からバーコード情報(数列)を取得した。
今回はこの情報から、商品情報を取得する。
取得方法のアイディア
実際このバーコード情報から商品名を求める方法はいくつかある。
今回はWebAPIを中心に話を進めるが折角なのでスクレイピングも少しみてみる。
1.スクレイピングする方法
例えば、JANコード「9000009984074」に対応するのは、お馴染み「クリスタルカイザー」という飲料水。
これを検索にかけてみるとこうなる。
BeautifulSoup4 をインストール
$ apt-cache search beautifulsoup $ sudo apt-get install python3-bs4
実装
python3.x系で実装するとこんな感じ
import urllib.request from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0", } request = urllib.request.Request(url='https://www.google.co.jp/search?q=9000009984074+jan', headers=headers) response = urllib.request.urlopen(request) html = BeautifulSoup(response) print(html)
2.WebAPIで検索する方法(種類)
脱線したがこちらが本筋。
WebAPIでバーコード情報から商品名を求められるメジャーどころは下記。
Product Advertising API (Amazon Web Services)
楽天商品検索API (Rakuten Developers)
Yahoo! Developer Networksを使ってみる
今回はまず手軽にやってみたいので、Yahoo! APIにした。
さらに、Yahoo! Developer Networksを使うモチベーションは、Yahoo!が提供する地図や気象情報などの多種多様なサービスがWebAPIから扱えるという点もあったので、今回登録してみた。
次の前提は把握していたほうが話がスムーズ。
- Yahoo! Developer Networksは、ディベロッパー(アカウント)登録が必要である
- 「アプリケーション」という単位で管理している
- 1アカウント当たり、10個までのアプリケーションを登録できる
- クエリ数は、アプリケーション通算の総カウントで計算される
- API別に上限がある
登録
ディベロッパー登録
まずディベロッパー登録を下記から行う。
Yahoo! JAPAN ID登録 - Yahoo! JAPAN
gmailでも登録できる。
アプリケーション登録
「アプリケーション管理」から「新しいアプリケーションを開発」を選択。
アプリケーションの種類を選択し、他の入力情報を埋める。
「クライアントサイド」を選択する場合はこんな感じ。
クライアントID取得
アプリケーションを登録後、「デベロッパーネットワークトップ」>「アプリケーションの管理」>「アプリケーションの詳細」から、「Client ID」をメモする。
ここでメモしたIDを、
インストール & 実装
必要モジュールをインストール
$ pip install beautifulsoup4
単なるWebAPIとして扱えるので「スクレイピングする方法」と似たように簡単だが今度はpython2.7系で実装するとこんな感じ。
import urllib from bs4 import BeautifulSoup // code : バーコード情報 def code_to_product_info(code): print('*********** start product_info ************') start_time = time.time() product_info = None client_id = '<client_id>' url = 'http://shopping.yahooapis.jp/ShoppingWebService/V1/itemSearch?appid={0}&jan={1}'.format(client_id, code) response = urllib.urlopen(url).read() soup = BeautifulSoup(response) res = soup.find_all('name') // nameタグを取得 //ここから超雑 if len(res) > 0: product_info = res[0] print 'proc_time {0:f} [ms] '.format((time.time() - start_time) * 1000) return product_info print('*********** end product_info ************')
結果
クリスタルガイザー ミネラルウォーター 500ml×48本 並行輸入品 代引不可
処理速度は50-150[ms]程度。(通信状況によって揺らぐ)
以上。
ここまでで、画像から商品名(食品名)を検索するモジュールができた。
次回からは、OCRを用いて画像から賞味期限を取得するモジュールの話を進めたい。
【python】zbarでバーコードを読み取る(画像→数列) 【お家IT#17】
本件の実装の一部
motojapan.hateblo.jp
前回の続き
motojapan.hateblo.jp
目次
前回まででフロントエンド・バックエンドの整備が終わった。
以降は、画像処理部分を進める。
今回は食品名(商品名)を取得するために、バーコード情報の読み取りをしたい。
バーコードとは
ふと、そもそもバーコードが何かをちゃんとわかっていなかったので調べる。
「黒いバーと空白の組み合わせで、数字、文字、記号を読み込めるデータ形式」であり、一般的に縞模様を光学系認識機器で読み取る。
一般に普及している縞模様の一次元バーコードや、QRコードに体表される二次元バーコードをよく目にしている。
今回は食品名を取得したいので、今回は一次元バーコードを中心に考える。
バーコードの詳細は次が参考になる。
バーコードとは?|基礎知識|自動認識|デンソーウェーブ
バーコード種類は下記。
- 統一商品コード(ユニークコード)
- インストアコード(任意コード)
特にユニークコードで、日本で使われているのはJANコード。
JANコード桁数は下記。
- 標準タイプ(13桁)
- 先頭7桁 : JANメーカーコード
- 先頭9桁 : 国番号2桁 + JANメーカーコード7桁
- 短縮タイプ(8桁)
JANコード構成要素は下記。
- 国番号+メーカー番号
- 商品番号
- チェックデジット
また、特に気になるのは、両サイドにあるマージンと呼ばれる空白は、十分な領域が必要である。<ナローバー(最も小さい黒縞)の10倍> ★
バーコードを読み込む方法は2つ思いつく。
- バーコードリーダーといった専用機器で赤外線反射から読み取る
- カメラなどの汎用機器で画像から読み取る(今回はこっち)
まぁこんな感じのバーコードリーダーでの読み取りでもよい。
RAINLAX バーコードスキャナ 無線対応 Bluetooth対応 ワイヤレスバーコードリーダー レーザーバーコードリーダー 手持ち式バーコードスキャナ 2.4GHz
- 出版社/メーカー: RAINLAX
- メディア: オフィス用品
- この商品を含むブログを見る
ただ、それはあまりにつまらないし、「自宅で手軽に使う」というポリシーから外れるのでので今回は画像処理ベースで調べてみた。(スマホ一台で済ませたいし。)
zbarインストール
かなり簡単
//インストール $ sudo apt-get install libzbar-dev $ sudo apt-get install python-zbar ... //確認 $ python import zbar //error無しでOK
インストール時のトラブルシューティング
「error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1」がインストール時に出る場合
下記インストール時にこんなエラーが出ることがある。
$ pip install zbar
対策 : module不足なので追加
$ sudo apt-get install python-dev
「segmentation fault」が実行時に出る場合
確認時(実行時)にこんなエラーが出ることがある。
$ python import zbar //segmentation fault
対策 : pipで入れたzbarがconflictしているようなのでpipはアンインストール、apt-getでインストール
$ pip uninstall zbar $ sudo apt-get install python-zbar
実装例
//img : cv2 image(numpy) def convert_image_to_code(img): print('=========== proc start =============') start_time = time.time() #init module scanner = zbar.ImageScanner() scanner.parse_config('enable') #image to gray gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) h = gray.shape[0] w = gray.shape[1] zimage = zbar.Image(w, h, 'Y800', gray.tostring()) #scan scanner.scan(zimage) result = [] for symbol in zimage: print('Type: {0} | Data: {1}'.format(symbol.type, symbol.data)) result.append({'type':symbol.type, 'data':symbol.data}) print 'proc_time {0:f} [ms] '.format((time.time() - start_time) * 1000) print('=========== proc end ===========') return result
結果
入力画像は★に注意して、実際にいくつか試してみるといい感じの結果となった。
平面紙印刷 |
レトレクパック印刷 |
曲面印刷 |
|
画像全体 |
|||
撮影領域 |
|||
結果 |
4970231640022 |
4902204411599 |
4902106232209 |
400 x 60 の画像に対して、処理速度は20-40[ms]程度。
曲面やぐにゃぐにゃ面でも割りとちゃんと認識できる。
以上。
次回はこのバーコードの数列から、食品名を取得する。
【Javascript】非同期実行を実装し、ボタンを押したフィードバックを全画面に行う 【お家IT#16】
本件の実装の一部
motojapan.hateblo.jp
前回の続き
motojapan.hateblo.jp
目次
前回までで、javascript/CSSを用いて撮影画面を作成した。
最後にUIの完成度を高めたいので撮影ボタンを押したらバックグラウンド全体が青くチカっとフラッシュするようにしたい。
そもそもの問題
ボタンを押したら、バックグラウンドの色をチカッっとしたい。
Windowsのメッセージで言うところのWM_LBUTTONDOWN と WM_LBUTTONUP のイベントが取れればよかったのだが、これに相当する関数が見つからなかったので、
onClick時に非同期メッセージを飛ばしてbackgroundカラーを変更することにした。
(ダサいのでいい方法あったら教えてください)
非同期にする方法
いろいろ調べたが、この資料がわかりやすい。
JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる - Qiita
実装
setTimeoutに非同期実行したい関数を設定する。
背景色の変更は、body.classNameに所望のレイアウトを指定することで可能。
//**************** css *********************** <style type="text/css"> ... .background_color_theme{ background: #ffffff; /*デフォルトの背景色*/ } .background_color_bt_pressed_theme{ background: #0000ff; /*フラッシュ用の青色*/ } ... </style> //************ javascript ******************** <script type="text/javascript"> function take_picture() { //前回までに追記 //(base64で画像を送信する実装) ... setTimeout(function(){body.className = "background_color_theme"}, 60); // 60 [msec]後に元のテーマに戻る body.className = "background_color_bt_pressed_theme"; } </script>
以上。
次回からは画像処理の話をしたい。
【CSS】接頭句の違い "#"と"." 【お家IT#15】
本件の実装の一部
motojapan.hateblo.jp
前回の続き
motojapan.hateblo.jp
目次
前回は、ボタンの透過度を設定した。
今回は、基礎的な話でなんとなく使っていたCSSの接頭句の違いを書く。
前々回のコードをコピーしたのが下記。
"."で開始するstyleは、classに対応
"#"で開始するstyleは、idに対応
classで記載しておくと同じstyleを適用できる。
//**************** html ********************** … <div class="l2"> <canvas id="camera_record_box"></canvas> </div> … //**************** css *********************** <style type="text/css"> … .l2 { top: 0px; /*動的に変更されるので適当*/ left: 0px; /*動的に変更されるので適当*/ width: 400px; /*撮影枠サイズ*/ height: 60px; /*撮影枠サイズ*/ position: absolute; /*absoluteに設定*/ padding: 0em 0em; } #camera_record_box{ position: absolute; /*absoluteに設定*/ border: 1px solid red; /*赤い撮影枠*/ padding: 0em 0em; } … </style>
以上。
次回でフロントエンド(webアプリ系統)の話は終えたい。
最後は簡単に非同期処理について、以降は画像処理の話をしたい。