しゃちの備忘録

これからC++を始める人によるC++の備忘録です(今のところ)

OCR(光学文字認識)について

本記事は,OCRをやってみたいなーっと思い始めた人の備忘録です. OCRとは何かから始まり,OCRを試す方法について調べたところまでまとめます.

コードとかはないです.ごめんなさい. 一応今後やる予定ではあります.

OCR(工学文字認識)とは

まずはOCR(Optical Character Recognition, 光学的文字認識)と呼ばれる技術について,簡単に説明をしたいと思います. OCRとは手書きや印刷された文字を,スキャナやカメラにより取得した画像などから読みとり,コンピュータ上で扱える文字に変換する技術のことを指します.

f:id:teru0rc4:20170716012626p:plain その手順は大きく4ステップに分かれています. 入力は上で軽く触れたように手書きや印刷された文字を画像化したものになります.

それらの画像に対して最初に行われるのがレイアウト解析です. 例えば新聞などを例に考えると,新聞の中には本文や見出しだけでなく写真などや緯線や罫線,枠などが存在します. これらの中でOCRの対象である文字を含む部分,本文や見出しなどの領域を解析します.

続いて行われるのは, レイアウト解析により文字があると判定された部分を行ごとに分けるステップです. 縦書きと横書きのケースとがあると思いますが, 個人的な感想ですが,横書きの方がいい制度が出るのかなという印象を受けました.

f:id:teru0rc4:20170716031556p:plain そして行ごとに分けられた文章を単語ごとに分解します. よく使われる手法としては横に広がる行に対して,上下方向にひいた線がどれくらい交わっているかを調べ,交わりっている部分が少ない部分を文字の切れ目と判定するという方法があるらしいです.(言葉にしにくいので何となく図にしました…) しかし,文字の感覚が狭かったり,この手法だけでは文字の境目だと誤検出してしまうような構造の文字もあるため, 正確に1文字1文字切り出すのは難しいそうです.

このような手順を踏むことで1文字1文字をデータ化し,行ごとにつなぎ直すことで文字全体のデータ化をしているらしいです.

OCRをためしてみる

そんなおCRを手軽(?)に試せる方法がいくつかあるらしいのでまとめました.

googleOCR

googleドライブからファイルをアップロードし,当該ファイルをgoogleドキュメントから開くことで,そのファイルに対してOCRを行なってくれるらしいです. パパッと使うならこれで十分そうです.

tesseract-ocr

tesseractとはGoogleで開発されているOCRエンジンです.(ここまで書いて上のgoogle Driveもtesseract使ってるんだろうなと気がつきました…)

各種言語からの呼び出しもできるようです. Pythonではpyocrというラッパーモジュールが存在しました.

まとめ

雑にOCRについて調べました. tesseractとpyocrについては今後使って見たいのでまた更新します.

おわりに

ブログ書きたいと思いつつ最近はいろんなことの調べごとの方が多くなってきたので,せっかくだしコード以外の調べごとも書いておこうということで書いてみました. とりあえずOCRについてでした. まとめの通り,近々コードに起こしたいですね….

virtualenvの使い方

備忘録. 新規性は全く無いけど,今後も使う可能性が高いので書いておきます.

Python仮装環境をまるっと作ることができるvirtualenvの準備から使い方までまとめておきます. よく一緒に話に上がることが多いpyenvとpyenv-virtualenvについても,名前と違いだけ触れておきます.

virtualenv

virtualenvとは/インストー

Pythonでの仮想環境を作成,管理できるパッケージです. パッケージなのでインストールではpipを用います(詳細は後述) これを用いる一つのメリットとして,同一バージョンだけど異なる環境を複数作成することができます

python3系の場合は以下のコマンドからインストールできます.

$ pip3 install virtualenv

pip3 listをして,virtualenv (xx.xx.xx)と追加されてれば完了です.

使ってみる

実際に使ってみます.今回はenv_test01という名前の環境を作ります.

$ virtualenv env_test01

これだけです.するとenv_test01というディレクトリができていると思います.この中にPythonの環境がまるっと入っている形になります.(いらなくなれば全部削除すればいいわけです) 上でも述べたように,virtualenvのメリットとして同一バージョン間の異なる環境構築が手軽にできるという点があります. 名前を変更してやればそのぶんだけ環境が作れるわけです.

オプションを指定しなければvirtualenvをインストールした環境と同じ環境が構築されます. 指定する場合は

$ virtualenv env_test02 -p python2.7

というふうにすると,異なるバージョンの環境を構築できます.

では作った環境を使って見ましょう. ディレクトリを移動して,bin/activateを対象に以下のコマンドを入力します.

$ cd env_test01
$ cd bin
$ source activate 

一行でsource env_test01/bin/activateでもいいとおもいます. すると先ほど作ったまっさらな環境に入ることができました. あとは好きにするだけです.

最後に入った環境の閉じ方だけ紹介して, 使い方解説は終了です,お疲れ様でした.

$ deactivate 

参考に私の環境での実行での様子を載せておきます. f:id:teru0rc4:20170627162950p:plain

似ているのの紹介

上で名前だけあげたpyenvとpyenv-virtualenvについて,名前と違いだけ触れておきます(個人的な備忘録)

pyenv

virtualenvと同じくPythonでの仮想環境を作成,管理できるパッケージです. 歴史的にはvirtualenvのが古いらしいです. バージョンが異なる環境を作れますが,モジュールを管理しているディレクトリが共通なので, 同一バージョン間で異なる環境がこれ単体ではできません. それを解決するのがpyenv-virtualenvのようです.

pyenv-virtualenv

pyenv-virtualenvはpyenvのプラグインになります. virtualenvとは無関係です(私も事前調査で混乱しました.混同して説明されているケースもあるので注意). これを使うことで,モジュールを別々のディレクトリで管理できるようになり,同一バージョン間で異なる環境が立てられるようになるようです.

終わりに

必要になって書いたのがひと月以上前なのですが,最後の使ってみる部分の記述をずっとしてなくて, ふと思い立って一気に書き上げました.

やりたいことを成すための調査→事前知識まとめ/方法決定→実行→ブログに起こす,までのステップで最後の部分をしっかりやりきることが少なく, これからはちゃんと最後までやりきりたいなーと感じたので, とりあえずここからやっていきます.

Pythonでwebアプリを作ってみる その2(SimpleHTTPServerを使う)

前回(Pythonでwebアプリを作ってみる その1 - しゃちの備忘録)の続きです.

SimpleHTTPServerを用いてシンプルなWebサーバを作って見ました. 個人的に忙しかったり,記事が消えたりしましたが私は元気です.

今回の目標

SimpleHTTPSerbverで,サーバーを立ち上げて何かを表示できるようになる.

Webサーバとは

Wikipediaによると以下の通り.

Webサーバ(ウェブサーバ)は、HTTPに則り、クライアントソフトウェアのウェブブラウザに対して、HTMLやオブジェクト(画像など)の表示を提供するサービスプログラム及び、そのサービスが動作するサーバコンピュータを指す。 広義には、クライアントソフトウェアとHTTPによる通信を行うプログラム及びコンピュータ。

クライアントからのリクエストに基づいて,なんらかのデータを返すのがサーバの仕事のようです. PythonではDjangoなどが有名だと思います.

SimpleHTTPServerでWebサーバを立てる

とりあえず,HTTPリクエストを返すシンプルなWebサーバを作成するということで,SimpleHTTPServerを使って見たいと思います. Pythonに標準モジュールとして入っているので,準備の手間が省けるのもポイントです.

なお今回は,Python3系を使用しています. 少しだけPython2系の場合にも触れますが,基本的にはPython3系で話を進めて行きます.

Pythonを起動し,コンソールに以下のコードを入力して見ましょう.

>>> import http.server
>>> http.server.test(HandlerClass=http.server.SimpleHTTPRequestHandler)

すると以下のような画面になります. f:id:teru0rc4:20170530145838p:plain

この状態でhttp://localhost:8000にアクセスして,ディレクトリリスト(じゃない場合もあり得る?)が見えていたらひとまずOKです..

ここまでの段階で,上で入力したコードにより,localhost(自分のPC)8000番ポートにサーバが建てられ, 上記アドレスにアクセスすることで,そこの状態が確認できる,と言った状態になりました. 特に指定しなければ,ポートは自動的に8000,が割り当てられます. もしサーバのポートを指定したい場合は,http.server.test(HandlerClass=http.server.SimpleHTTPRequestHandler, port=8001)と言った風に最後にport = *****といった記述を追加してあげて下さい. 特にサーバに関しての設定等を行なっていないので,ひとまずは自分のディレクトリの中身がみれるという状態になります.

本当に最低限ではありますが,これでサーバ立てはできました. 建てたサーバの停止方法は,Ctrl + Cになります.これをしないとこれ以降サーバを建てる時に前回以前の建てたサーバが残ってしまい,指定したポートにサーバを立てられないことが起こるので気を付けましょう.(その場合,サーバの当該プロセスを探してkillすればいいので,そこまで焦る必要もないです.方法は後述)

ワンライナーでサーバを起動する方法

もう一つ,SimpleHTTPServerでサーバをささっと立てる方法を記述しておきます. 先ほどはPythonのプロンプト場での入力でしたが,今回はPythonプロンプトを立ち上げる前の段階でのコマンドになります.

$ python3 -m http.server

このようにすると上と同じようにサーバを構築できます,ポート番号を指定したい場合はpython3 -m http.server 8001のようにするとできます.

サーバがうまくたたち上がらない場合

上で述べたコマンドを実行した場合に,下のようにAddress is already in useと出ることがあります. f:id:teru0rc4:20170530151328p:plain

このようなメッセージが出る場合,サーバを立てようと指定したポートにすでにサーバが立ち上がっている(前回以前にちゃんとkillできていなかった)ことが起きています. なので,残ってしまっているプロセスをキルしてあげる必要があるのです.

立ち上がっているサーバのプロセスをキルしたい場合

psコマンドを使うことで,現在立ち上がっているプロセスの確認ができます. f:id:teru0rc4:20170612153313p:plain

その中にhttp.server ****(****はポート番号)というプロセスがあるはずです. 今回はこのプロセスをキルします. 該当プロセスのPID(プロセスID)を確認し,kill -15 *****と入力します. -15とすることで,プロセスの強制終了ができます.

今回の例では以下のような感じになってます. キルが実行され,該当プロセスが消えているのがわかると思います. f:id:teru0rc4:20170612153622p:plain

おわりに

この後どうしようかなーと思っていたのですが,そのうちにひと月経ってしまったので, ひとまずここまで公開します.

次は立てたサーバで何か動かすところからやりたいと思います.

追記

SimpleHTTPServerで作業する内容もう少し続くのかなと思ったら動的なものを作ろうと思ったら使わなそうなので, そのあと調べたことを追記してSimpleHTTPServer関連の話はここで打ち切りたいと思います.

サーバアクセス時の処理について

今回使用したSimpleHTTPSerbverを上のような手順で使用した際,サーバ立ち上げたときディレクトリのリストが出力されたと思います.(厳密には現在の作業ディレクトリのリスト)

これはSimpleHTTPSerbverに, サーバを立てた時のディレクトリに「index.html」,「index.htm」がある場合,それらを開く. ない場合はディレクトリリストを開くという実装になっているからです.(ので前回は~/のディレクトリリストが取得されたのです)

詳しい話はdo_GETの中(send_head)に定義されていました. github.com

index.html以外を開く場合はそれようのオプションもあるので,困ることはないと思います. ので,実際にディレクトリリスト以外を表示するところまでやって見たいと思います.

index.htmlを記述し動かす

今回は以下のようなファイルを作成しました. ファイル名はindex.htmlとしてください.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>SampleHTML</title>
  </head>
  <body>
    <p>Python is awesome!</p>
  </body>
</html>

またサーバーを起動するスクリプトも,ファイルに保存してしまいたいと思います. ***.py(***は何でも良い,今回は暫定的にserver.pyとして話を進めます)という名前で保存します.

import http.server
http.server.test(HandlerClass=http.server.SimpleHTTPRequestHandler)

これら2つのファイルを同じディレクトにいれ保存してあげてください. f:id:teru0rc4:20170711154241p:plain

そして,server.pyを実行します.

$ python3 server.py
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

f:id:teru0rc4:20170711154602p:plain

するとこんな風に先ほどindex.htmlに記述されたwebページが出力されました. このようにindex.htmlを表示するだけですがこれでwebサーバが建てられました.

しかし,これでは静的な変化のないサイトの記述しかできません. 次回は動的なサイトを記述できるよう,別のモジュールを使いたいと思います.

Python3での競技プログラミング用標準入力個人的まとめ

githubに書いてた内容を移植しました. ほとんど差はないです.

Python3で競技プログラミングをする時に, テストケースをなんとか簡単に実行したいというのと,標準入力のやり方について気になったのでまとめました. 参考になれば幸いです.

テストコードテンプレ

solve()以下に実際のコードを記述し, テストケースを入れたフォルダへのパスを書いてあげると,そのフォルダ内全てのファイルの内容を標準出力にして、テストを行います. 提出時はsolve()の内容をまるまると,solve()のコメントを解除してあげます **********は対象のフォルダへのpathを書いてください.

# -*- coding: utf-8 -*-
import sys
import os

##### solveの中に記述,提出時はsolve()のコメントアウトを外して
##### ここから
def solve():
    a, b, c = list(map(int, input().split()))
    if a <= c and c <= b :
        print("Yes")
    else:
        print("No")
# solve()
##### ここまで

test_path = 'test_case'
FILES = os.listdir(test_path)
print('test case => %s\n**********' % FILES)
for FILE in FILES:
    fdr = os.open(test_path + '/' + FILE, os.O_RDONLY)
    print("\ncase : %s" % FILE)
    os.dup2(fdr, sys.stdin.fileno())
    solve()

print("\n**********\nfinish")

こんな感じで試しています. f:id:teru0rc4:20170514193019p:plain

標準入力受け取りテンプレ

標準入力には様々なパターンがありますが,これだけ使えれば良さそうというものだけ書いておきます.

入力が1行で1つだけの場合

文字・文字列

input

S

Sは文字列

s = input()
数値(整数または浮動小数点数)

input

N

Nは整数または浮動小数点数.

n = int(input()) # 整数
n = float(input()) # 浮動小数点数
  • raw_input()が削除され, input()に一本化された
    • python2では, 文字列はrow_input()であった
  • 数値をinput()する場合は, それぞれの状態に応じてキャストしてやる必要がある.
    • 小数点数をintでキャストすると値が切れるので注意

入力が1行で複数ある場合

文字・文字列

input

A B C

A,B,Cはいずれも文字列

s = input().split()
a, b, c = input().split()
  • 分割された文字列はinput().split()でOK
    • 異なる変数に代入したい場合はa,b,cのようにすれば, スペース区切りで各変数に入力される.
数値(整数または浮動小数点数)

input

A B C

A,B,Cはいずれも整数または浮動小数点数.

n = list(map(int, input().split())) # 整数
n = list(map(float, input().split())) # 浮動小数点数
n1, n2, n3 = list(map(int, input().split())) # 整数
n1, n2, n3 = list(map(float, input().split())) # 浮動小数点数
  • python2の頃と見た目はそんなに変わらないが実態が異なる

入力が複数行で1つずつ与えられる場合

最初に入力する個数(N)が与えられて, そこからN個の入力が与えられる場合

input

N
a1
a2
...
aN

a1,a2,…,aNはN個の入力.

N = int(input())
a = []
for i in range(N):
  a.append(input())

あるいは

N = int(input())
a = [input() for i in range(N)]
  • まず個数Nを受け取って, そのあとN個の入力を格納する
  • listの内包表記を使うと美しい……
    • intで取り扱いたいならinput()をキャストすること
終了フラグが来るまで入力を格納し続ける場合
a = []
while True:
    n = input()
    if n == -1: # 終了フラグ
        break
    a.append(n)
  • 判定の部分を文字か数字かでわしゃわしゃする必要はある
    • あまりみたことないけど一応
    • EOFの場合はどうすればいいんですかね……

入力が複数行にわたって複数与えられる場合

input

N M
a11 a12 a13 ... a1M
a21 a22 a23 ... a2M
a31 a32 a33 ... a3M
...
aN1 aN2 aN3 ... aNM
N, M = list(map(int, input().split())) # 整数
a = []
for i in range(N):
    a.append(list(map(int, input().split())))

Pythonでwebアプリを作ってみる その1

いろんな事情でwebアプリをちゃんと作りたくなったのでちょっとづつ書きます. 半分日記. 完成したら,ちゃんとまとまった内容の記事かくかもしれないけど,ひとまずつらつらと. しばらく忙しくなるけど,最悪でも週1ペースで書いておきたいです.

最終目標

なんかwebアプリを完成させます.内容はともかくとしてとりあえずなるはやで完成を目指します.

今日の進捗

今後どうするかについて精査しました. このブログを参考に進めさせていただきたいと思ってます. みんなのPython Webアプリ編 - PythonでWebサーバを作る | TRIVIAL TECHNOLOGIES 4 @ats のイクメン日記

多分次回更新は数日後, SimpleHTTPServerをつかったあれこれについてだとおもいます.

  • 手持ちの知識でできることは,html/css/javascriptを書くこと, pythonを書くこと.
  • やったことないことは,pythonでサーバサイドを構築すること.
  • サーバサイドで,Pythonの場合DjangoやFlaskといったwebフレームワークが使われることが多いらしい
    • 聞いたことはある,触ったことはない
  • どこかのサイトか本を参考にとりあえず一つやり切ってみる
  • どうやら標準モジュールだけでもそれっぽいことはできるらしい?
    • SimpleHTTPServer
    • ひとまずそっちやってみる

Macのスクリーンショットの保存場所を変える方法

個人的に気になったのでメモ.

Macスクリーンショットはデフォルトでは, “デスクトップ"に"png"形式で保存されます. これを, どこか別のフォルダに任意の形式で保存したいと思います.

そのためにはターミナルから設定を変更してあげなければいけないらしくそれの備忘録を書いておきます.

保存形式の変更

画像の保存形式変更には以降のコマンドのいずれかを,ターミナルから入力する必要があります.

$ defaults write com.apple.screencapture type bmp
$ defaults write com.apple.screencapture type gif
$ defaults write com.apple.screencapture type jpg
$ defaults write com.apple.screencapture type pdf
$ defaults write com.apple.screencapture type png
$ defaults write com.apple.screencapture type tiff

デフォルトではpngになっているので変えたい場合は,それぞれの形式に合わせて末尾を変えれば良いらしいです.

また上のコマンドの後に,システムの再起動が必要らしく以下のコマンドを入力してあげます.

$ killall SystemUIServer

保存場所の変更

こちらもコマンドで指定します. ~/screenshotに保存するケースのコマンドなので読み替えてください

$ defaults write com.apple.screencapture location ~/screenshot

この場合システムの再起動が必要なようです.

$ killall SystemUIServer

元の状態に戻すなら以下のようです.

$ defaults delete com.apple.screencapture location
$ killall SystemUIServer

MacでSourceTreeを使いGithubに接続するまで

タイトルの通り, MacでSourceTreeを使いGithubに接続するまでを備忘録的にまとめておきます. Githubの準備とかは省略します.

それ以外の手順は以下の通り.

  1. SourceTreeを準備する(アカウントを作る&クライアントをインストール)
  2. SSHの準備をする
  3. SourceTreeとGithubSSH接続で接続する

SourceTreeを準備する

SourceTreeとはAtlassianが提供しているGitクライアントソフトです. 一番のメリットはGitでのコマンドをGUIでの操作できる点だと思います.(もちろんコマンドを知っていることでより高度な操作ができたりするので知らなくていいというわけではない)

肝心のSourceTreeですが, 下のサイトからダウンロードできます. ja.atlassian.com

ダウンロードされるzipを展開し, appファイルを起動してあげます. f:id:teru0rc4:20170322180928p:plain ここからAtlassianアカウントを作成したり, 既に持っている場合は登録したりしてあげます. それほど面倒じゃないのでサクサク設定してあげましょう.

アカウントの認証が終わると, BitBucketやGitHubなどのリモートリポジトリとの連携について聞かれます. ここで設定することも、セットアップ完了後に後から設定することも可能になってます. 今回はとりあえず「後から設定」を選んでおきます.(あまり意味はないです…)

SSHの準備をする

上でSourceTreeの準備ができたので, GithubとSourceTreeを繋ぐためのSSHキーを生成します.

Windowsの場合, 標準でSSHを使用することができない関係で, SourceTreeにSSHに関するものがまとめて付属しているのですが, Macではついていません.(SSH接続の際OS側のOpenSShを使用するため) ので, ターミナルを操作してSSHキー生成を行なっていきます.

MacSSH公開鍵認証のキーは, 隠しディレクトリの.sshに格納されます. もし .sshディレクトリが存在しない場, 以降の操作の中で作成されるので特に気にする必要はないようです.

ではsshのキーを生成します. ここで使用するコマンドはssh-keygenになります. これを使用することで, キーの生成や, 管理等々を行うことができます. いろいろ聞かれるので, 元々のメッセージにコメントの形で解説を添えておきました.

$ ssh-keygen -t rsa
Generating public/private rsa key pair.          # -t rsaを指定したので, rsaを作りますよ的なメッセ
Enter file in which to save the key (/Users/teru0rc4/.ssh/id_rsa):          # この名前で鍵をつくるよ的メッセ, enterするとid_rsaという名前が自動的につきます. 何かつける名前がある場合はここで入力してあげてください.
Created directory '/Users/teru0rc4/.ssh'.          # .sshディレクトリがないので作りましたよ, すでにあるなら言われないようです
Enter passphrase (empty for no passphrase):          # パスフレーズ入力
Enter same passphrase again:          # もう一回パスフレーズ

ssh-keygen -t rsaとすることでrsa暗号の鍵を作成することができます. 生成の時のコマンドをssh-keygen -t rsa -C hogeとすることで鍵にコメントをつけることができます.(こんかいはhogeというコメントがつきます, メールアドレスとか用途とかをシンプルにコメントでつけることがあるみたいですね)

ほかにも, 鍵につけたパスフレーズの変更をするオプション(-p)や, 鍵ファイルを変換するオプション(-f)などがあるようですが, ここでの説明は控えておきます.

ともかくこれで, .ssh以下に公開鍵id_rsa.pub秘密鍵id_rsaが生成されていると思います.

最後に, この鍵をsshエージェントに保存します. ssh-addを使うことで, 先ほど作った鍵を登録してあげます.

$ ssh-add ~/.ssh/id_rsa

パスフレーズを入力してIdentity added:~~~のようなことが出ればOKです.(ssh-add -lで確認もできます.)

SourceTreeとGithubSSH接続で接続する

それでは最後に, SourceTreeとGithubとを接続します.

まずは先ほど, 生成した鍵の内容をコピーします.(鍵の名前を変更している場合読み替えてください)

pbcopy < ~/.ssh/id_rsa.pub

これでクリップボードに, 鍵の内容がコピーされたはずです.

次はGithubの設定をします. Githubの自分のページに行きSettingをひらきその中の, SSH and GPG keysを選択, New SSH Keyをクリックし鍵を追加します. Titleはなんでも良いのですが, どのパソコンで使っている鍵かどうかなど自分で区別できる名前を使ってあげましょう. Keyの部分でクリップボードの内容を全てコピーしてやり, Add SSH keyで登録完了です. f:id:teru0rc4:20170324211150p:plain

最後に, SourceTreeで自分のGithubリポジトリを操作できるように登録してあげます. Github上でCloneしたいリポジトリを開き, Clone or downloadをクリックします. 展開されたウィンドウのクリップボード?のようなアイコンをクリックすると, クリップボードに内容がコピーされます. Github側の準備はこれで終わりです. f:id:teru0rc4:20170324213608p:plain

SourceTree側の設定を行います. +新規リポジトリ->URLからクローンを選択します. f:id:teru0rc4:20170324213637p:plain

ソースURL部分に先ほどコピーしたGithubのURLをコピーし, パスの部分に自分のPCの保存したいディレクトリパスを入力してクローンを押します.

そうするとクローンが完了し, SourceTree上からGithubを操作できるようになります. お疲れ様でした. f:id:teru0rc4:20170325001644p:plain