Google Cloud Vision APIでPDFにOCRをかけてみた

給与明細にOCRをかけて自分の給与を記録したい 会社から発行される給与明細はPDFファイル。しかもフォント埋め込みで埋め込まれてるフォントが有償?恐らく通常手に入らないRICOHのフォント。 データを抜き出せないかとGoogleDriveでPDFからGoogleDocumentsに変換してみたり、各種ツールでwordとかテキストに変換してみようとしたが一切うまくいかない。 そもそもコピペすらできない(コピペしようとしてもフォントが無いから?????になる) ということでOCRをかけてみた。 OCRの機能差 調べてみたところ、AzureやAWSにもOCRを使う機能はある。 しかし認識率についてはGoogleがトップであるようだったので、GCPを利用してみることにする。(普段AWSばかり触っているのでたまにはGCPも触ってみようと思った、というのも理由) Google Cloud Vision API (Go言語) ということでGo言語でGoogle Cloud Vision APIを利用してみた。 と言ってもほぼサンプルのままで動作する。 事前準備 先にGoogle Cloud Storageに対象となるpdfファイルを置いておく必要がある。 またバケットに対して読み取り、書き込みの権限も付与してある必要がある。 なお今回はローカルで動作させるのでサービスアカウントのキーを作成しておく。 参考: https://cloud.google.com/vision/docs/quickstart-client-libraries?hl=ja 事前に環境変数として発行したキーをexportしておく。 export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json" ソースコード ほぼサンプルのままで動作する。 結果は dst_uri := "gs://path/to/result.json" にjsonとして保存される。 // Sample vision-quickstart uses the Google Cloud Vision API to label an image. package main import ( "context" "fmt" "os" "io" vision "cloud.google.com/go/vision/apiv1" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) // detectAsyncDocument performs Optical Character Recognition (OCR) on a // PDF file stored in GCS. [続きを読む]

TypeScriptに入門したいのでJavaScriptに入門してみる(文と式)

続: JavaScript入門 これ の続き。 教材は https://jsprimer.net/ 文と式 JavaScriptは文と式で成り立つ。 式は評価すると値を得ることができ、この値のことを評価値と呼ぶ。 文は処理の一部として式を含むことがある。 式文 式は文になることができる。文となった式のことを式文と呼ぶ。 条件分岐 if, else if, else 省略 switch文 switch は言語によって結構差がある部分なので一応メモする。 switch (式) { case ラベル1: // something to do break; case ラベル2: // something to do break; default: // something to do break; } C言語などと同じですね。breakを忘れるとその下のcaseの内容も実行される。 ループと反復処理 while, do-while, for C言語と同じ。省略。 配列の forEach メソッド 他の言語と似てるが、メソッド名が forEach (Eが大文字) ですね。 // forEachにはコールバック関数を渡す const array = [1,2,3]; array.forEach( currentValue => { // 配列の要素ごとに呼び出される処理 }); 実例 [続きを読む]

TypeScriptに入門したいのでJavaScriptに入門してみる(関数と宣言)

続: JavaScript入門 これ の続き。 教材は https://jsprimer.net/ 関数と宣言 関数は function キーワードを使う。 function function_name(arg1, arg2) { // something to do... return return_value; } // 関数の呼び出し const result = function_name(arg1, arg2); 関数名のルールは変数名のルールと同じ 半角のアルファベット、_ (アンダースコア)、$ (ダラー)、数字を組み合わせた名前にする 変数名は数字から開始できない 予約語と被る名前は利用できない returnは必須ではない(値を返す必要がない関数はreturnを書く必要はない) returnの返り値を省略している場合、もしくはreturn 文のそのものを省略した場合は未定義の値である undefined を返す。 関数の引数 定義した関数の仮引数よりも呼び出し時の引数が少ない場合、余った仮引数には undefined という値が代入される。(エラーにならないんですね…) function echo(x) { return x; } console.log(echo(1)); // -> 1 console.log(echo()); // -> undefined また、引数の数が多い時は余分な引数は単純に無視される。 [ES2015] デフォルト引数 Pythonなどと同じくデフォルト引数が使える。 function echo(x = "hoge") { return x; } console. [続きを読む]

TypeScriptに入門したいのでJavaScriptに入門してみる(暗黙的な型変換)

続: JavaScript入門 これ の続き。 教材は https://jsprimer.net/ 暗黙的な型変換 等価演算子などで暗黙的に型変換される例が載っているが、必要性は薄く基本的には === を使うようにすべき。 暗黙的な変換は割とひどい仕様が載っている… 明示的な型変換 任意の値 -> 真偽値 Boolean("string"); // -> true 任意の値を真偽値に変換できるが、どの値がtrueに、どの値がfalseになるのかは falsy な値が falseになる falsy でない値は true になる というルールに従う。 falsy な値とは以下の6種類である。 false undefined null 0 NaN ”” (空文字) 数値 -> 文字列 String(1); // -> 1 真偽値に対しては Stringで true または false という文字列になる。同じように null, undefined, シンボルのプリミティブ型の値に対しては変換は見た目通りの文字列を得ることができる。 オブジェクトを文字列にしたい場合は、 JSON.stringify などのより適切な方法を使うべきである。 シンボル -> 文字列 String(Symbol("シンボルの説明")); 文字列 -> 数値 ユーザからの入力を数値にする場合などに使う。 [続きを読む]

TypeScriptに入門したいのでJavaScriptに入門してみる(演算子)

続: JavaScript入門 これ の続き。 教材は https://jsprimer.net/ 演算子 + での文字列結合 const value = "hoge" + "moge"; console.log(value); // -> hogemoge 数値計算 JavaScriptでは数値は内部的には IEEE 754方式の浮動小数点数として表現される。よって整数と浮動小数点数の加減乗除も + ,- , * , / , % で実行可能。 [ES2016] ** べき乗演算子 ES2016から使えるべき乗を求める演算子 ** なお、旧来は他の言語と同じく Math.pow といったメソッドを利用していた様子。 console.log(2**4); // -> 16 console.log(Math.pow(2, 4)); // -> 16 単項 + または - 演算子 単項演算子の + はオペランドを数値に変換する(マイナスも同様) つまり文字列の "1" を 数値の 1 に変換してくれる。 let t = +"1"; console. [続きを読む]

TypeScriptに入門したいのでJavaScriptに入門してみる(nullリテラル~データ型とリテラルの最後まで)

続: JavaScript入門 これ の続き。 教材は https://jsprimer.net/ nullリテラル null 値を返すリテラルで、「値がない」ことを表す。 nullを参照した場合コンソール上では null と表示されるだけである。 undefined はリテラルではない undefined はただのグローバル変数で、undefinedという値を持っているだけ。したがって同じ undefined という名前のローカル変数を宣言することができる(もちろん非推奨) function fn(){ var undefined = 100; console.log(undefined) } fn(); true, false, null は変数ではなくリテラルであるため、同じ名前の変数を定義することができない。 オブジェクトリテラル const obj = { key: "value" }; オブジェクトの keyには 文字列またはSymbol を指定し、値にはプリミティブ型からオブジェクトまで何でも入れることができる。 オブジェクトが持つキーのことをプロパティ名と呼ぶ。※ここでは key がプロパティ名。 オブジェクトのキーを参照するにはドット . またはブラケット [] を利用する。 const obj = { "key" : "value" }; console.log(obj.key); console.log(obj["key"]); ドット記法ではプロパティ名が変数名と同じく識別子である必要があるので、数値から始まるような識別子は利用できない。 配列リテラル const emptyArray = []; // 空配列 const array = [1, 2, 3]; 配列の添字は 0 から始まる。他の言語と同じ。 [続きを読む]

DIYで家のネットワークをcat6aにした場合の費用はどのくらい必要か

新築時にcat6aケーブルを敷設する

持ち家のいいところの一つに、家の色々な部分を変更できるという点がある。 家を作るときに情報コンセント(モジュラージャック)を付けて、入居前に宅内LANを敷設してもらうことももちろん可能だ。 しかし家を建てるときに住宅メーカーにやってもらった場合、5箇所で10万~20万程度はかかってしまう。 更にcat6aなどは対応してくれない業者もあるので,それなら空配管だけ通しておいてもらって自分でやろう!と思った次第。

cat6aをDIYで配線する場合の費用概算

必須

cat6a ケーブル

100メートルでおおよそ1.5万円ほど。3LDK程度の家なら100メートルも要らないが、50メートルなどは見当たらないのと、空配管がどのようなルートで通っているのか建築後は把握できないため、余裕を持った長さを買った方が良い。

もっと短くても問題ないという確信があれば50メートル程度の端子のついたものを買って、端子部分を切って使う手もある。

モジュラージャックと成端補助工具

壁に情報コンセントを埋め込む。ホテルや会社の会議室などの壁にあるLANケーブルの差込口である。 日本製線という会社が出しているCat6A用JISアダプタキットが5セットで8000円程度。

cat6までであればPanasonicのぐっとす情報モジュラージャック、という有名な(そしておそらくDIYでやる人にとってはデファクトスタンダードな)ものがあるのだが、残念ながらcat6a対応は発売されていない。cat6まででOKなら一つ1000円程度で買うことができるためコストは抑えられる。

日本製線のものもパンドウィットのものも、成端補助工具があるときっちりはめ込めるのであったほうがよい。

通線ワイヤー

5000円~1万円程度。空配管の中をLANケーブルを通すための道具。

無くてもできるという人もいるが、個人的には絶対にあったほうが良いと思う。ビニールテープで通したという情報もネットで見て挑戦してみたが、空配管にうまく掃除機のノズルを当ててやって吸い込む必要があったり、空配管の角度がきついところを通すときは強く引っ張る必要がありその際途中で切れてしまうリスクがある。

通線ワイヤーならそんなリスクもないし、掃除機のノズルを頑張って当てる必要もない。

工具類

かしめ工具/圧着ペンチ(3000円~5000円程度)、皮膜剥き(2000円)、ニッパーがあればとりあえず何とかなる。

皮膜剥きは一応カッターなどでも代用できなくはないが、芯線に傷を付けたりして作業効率が悪くなるのであったほうがよい。

あると作業効率があがるもの

シリコンスプレー

LANケーブルを空配管に通線時にこれを吹き付けながら通していくと、抵抗少なくスルスル入っていくので力任せに引っ張る必要がなくなり非常に良い。 無くてもどうにかなるがあったほうが作業効率が上がる。

なお吹き付けながら通す必要があるので、LANケーブルを入れていく方に人がもうひとり必要になる。

スパイキ

LANケーブルの芯線は撚ってあるので、それをとくための道具。あれば楽だが無くてもどうにかなる。

総額

3.5万円~4万円程度となる。対応箇所が少ない場合は新築時に対応してもらったほうが安く上がるが、cat6a以上のケーブルを敷設したい、といった要望がある場合にはDIYが視野に入るかと思う。

TypeScriptに入門したいのでJavaScriptに入門してみる(変数~文字列リテラルまで)

動機 WebUIをある程度作れるようになりたい(個人の趣味レベルだけど)と大昔から思っていたものの、当時はJavaScriptのFWだったりJavaScriptのトランスパイラだったりが沢山出てきていたような印象があり、遠巻きにWebのUIを作るのは怖い!と思っていた。 社会人になってもCでUIも無いようなプログラムを書くことしかなかったのと、その間にクラウドが進化してAWSやGCP, Azureを使えること自体が技術としてみなされるようになってきたこと、golangやRustが出てきてそちらに興味が湧いてきたこともあり、ますますチャレンジする機会を逃していた。 (そもそも型のある言語の方が好きだったりする) しかしここ2,3年ほどでTypeScriptは型もあって概ね好評だし流行ってきて今後も使われそう、ということで入門したくなった。 ところがTypeScriptをやってる人に聞くとJavaScriptを知らないと難しい、とのことだったのでとりあえずJavaScriptに触ることにした、という長い背景がある。 教材 よく知らないのだが、WebUIに関してはmizchiさんという恐らく有名な?方が 「TypeScript入門以前ガイド」というのを書いて下さっていて、このガイドによるところの私は ES2015 for Beginnersにあたる。 https://mizchi.hatenablog.com/entry/2018/10/03/195854 そこでおすすめされている https://jsprimer.net/ を使って進めていこうと思う。 第一部:基本文法 プログラミング自体が初めてというわけではないので、気になった部分だけをメモしていく。 変数と宣言 変数の宣言は constまたはletで行う。 const は再代入ができない変数、letは再代入可能な変数の宣言。 varはES2015ではすでに非推奨であり、使うべきではないが、互換性のために残されている。 const const hoge = "Hello"; const は必ずしも定数”ではない”ことに注意する。 constでオブジェクトを宣言することもできるが、オブジェクト自体は変更可能である。 let let hoge = "Hello"; let hoge hoge = "World"; hoge = 1; letは再代入可能な変数で、初期値を定義せずとも宣言可能。初期値を定義しなかった場合は “undefined” になる。 undefined は null とは異なる。C言語と同じく不定、ということだろう。 varの問題点 letやconstでは同じ名前の変数を再定義することはできないが、varではできてしまう。 またvarには「変数の巻き上げ」と呼ばれる意図しない挙動があるらしい。 変数名のルール let, const ともに変数名には以下の命名規則がある。 半角のアルファベット、_(アンダースコア)、$(ダラー)、数字を組み合わせた名前にする 変数名は数字から開始できない 予約語と被る名前は利用できない この辺は他の言語とほぼ同じ。一応マルチバイト文字も変数名に使うことができるらしい。 値の評価と表示 ブラウザのREPL(read-eval-print-loop)と呼ばれる機能(開発者向けコンソール)を使って直接JavaScriptを記述して試すことができるよ、という紹介。 [続きを読む]

続:Terraformに入門してみた(Lambda)

続: Terraform入門 これ や これ の続き。 今回は terraformで lambdaを管理してみる。ただし terraform での Lambdaの管理は辛いというような意見が散見されるので、良い方法ではないと思われる。 まぁあくまでも入門ということで。 公式はページ ここ terraformのコード data "archive_file" "lambda_zip" { type = "zip" source_dir = "${path.module}/src" output_path = "${path.module}/lambda_function_payload.zip" } resource "aws_lambda_function" "test_lambda" {# zipで固めたソースコードを指定する。ライブラリも含めて固める必要がある filename = "lambda_function_payload.zip"# Lambdaの関数名 function_name = "lambda_function_name"# Lambdaの利用するrole のarnを指定する role = "${aws_iam_role.iam_for_lambda.arn}"# 呼び出しのhandlerとなる関数 handler = "exports.test"# SHA256のhashをbase64でエンコードしたもの。 # zip化したファイル名を指定してあげれば良い。 source_code_hash = "${filebase64sha256("lambda_function_payload.zip")}"# 利用するランタイム, # pythonなら"python3.6" といった感じにかける。 runtime = "nodejs8.10"# タイムアウトの秒数指定 timeout = 300# 環境変数 environment { variables = { foo = "bar" } } } 注意点 Lambdaのソースコード自体は archive_fileで固めることができるが、 source_dir 、output_pathは相対パスだとうまく動かなかったので、 ${path. [続きを読む]

Ubuntu18のaptでインストールしたpip3ではtargetオプションを使ってもExceptionが発生する(Ubuntu18.04)

pip3でtargetオプションを使って特定ディレクトリにライブラリをインストールしたい $ pip3 -V pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6) このpip3はaptでインストールしたもので、バージョンが低くtargetオプションがそもそも存在しないようだ。 $ pip3 install requests -t workspace/ Collecting requests Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl Collecting chardet<3.1.0,>=3.0.2 (from requests) Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests) Using cached https://files.pythonhosted.org/packages/81/b7/cef47224900ca67078ed6e2db51342796007433ad38329558f56a15255f5/urllib3-1.25.5-py2.py3-none-any.whl Collecting certifi>=2017.4.17 (from requests) Using cached https://files.pythonhosted.org/packages/18/b0/8146a4f8dd402f60744fa380bc73ca47303cccf8b9190fd16a827281eac2/certifi-2019.9.11-py2.py3-none-any.whl Collecting idna<2.9,>=2.5 (from requests) Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl Installing collected packages: chardet, urllib3, certifi, idna, requests Exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main status = self. [続きを読む]