HRR Co., Ltd.

技術的な記録を残していくことを目的としています。1次情報を大事にしています。

画像にある数字を抽出したい

はじめに

タイトル通りですが…そういうニーズが発生しました。
画像をいちいち目で確認していくのは、大変な労力がかかります…。

この手のことは、やはりPythonでやるものではないか?という先入観の元、調べていたのですが…。
TesseractというOCR (Optical Character Recognition/Reader、光学的文字認識) エンジンがあるとのことで、まずそれを試してみることに。
日本語で書くと「テッセラクト」ですかね。

環境はWindows7Cygwinを使用しております。

まずはインストール

こちらを参考にしております。
github.com

まずはapt-cygにて検索をかけます。

$ apt-cyg searchall tesseract
libtesseract-ocr_3
tesseract-ocr-deu
tesseract-ocr-devel
tesseract-ocr-eng
tesseract-ocr-fra
tesseract-ocr-ita
tesseract-ocr-nld
tesseract-ocr-por
tesseract-ocr-spa
tesseract-ocr-vie
tesseract-ocr
tesseract-training-core
tesseract-training-deu
tesseract-training-eng
tesseract-training-fra
tesseract-training-ita
tesseract-training-nld
tesseract-training-por
tesseract-training-spa
tesseract-training-util
tesseract-training-vie

すると出てきますね…ぞろぞろと。
メインどころであろう、下記パッケージをインストールしてみます。

$ apt-cyg install tesseract-ocr

すると長いログが出る出る…依存性のあるパッケージが次々とインストールされているようです。
整理してみると、こんな感じでした。
cygwinは抜いてます。
※一部再帰的になっていますが気にしない方向で。

tesseract-ocr
├ libgcc1
├ libleptonica_5
│ ├ libgif4
│ │ └ libX11_6
│ │    └ libxcb1
│ │       ├ libXau6
│ │       └ libXdmcp6
│ ├ libjpeg8
│ ├ libpng16
│ │ └ zlib0
│ ├ libtiff6
│ │ ├ libjbig2
│ │ ├ libjpeg8
│ │ ├ liblzma5
│ │ ├ libstdc++6
│ │ └ zlib0
│ ├ libwebp5
│ └ zlib0
├ libstdc++6
├ libtesseract-ocr_3
│ ├ libgcc1
│ ├ libleptonica_5
│ └ libstdc++6
└ tesseract-ocr-eng
   └ tesseract-ocr

これを見る感じ、画像形式はjpg, gif, png, tiffには対応できていそう。
言語パッケージはデフォルトは英語だけみたいですね。
バージョン情報を確認してみます。

$ tesseract --version
tesseract 3.04.01
 leptonica-1.73
  libgif 4.1.6(?) : libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.6.24 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.4

うん、入ってますね。

実際に使ってみる

というわけで、実際にお試しです。
適当にペイントソフトで作成した画像で、コマンドを叩いてみます。

f:id:hrroct:20170124170206p:plain

コマンドはWikiにもある通りです。

tesseract imagename outputbase [-l lang] [-psm pagesegmode] [configfile...]

・第一引数:画像
・第二引数:出力ファイル名
を最低限渡せばよさそうです。

$ tesseract NumberImage.png out
Tesseract Open Source OCR Engine v3.04.01 with Leptonica
Error in pixGenHalftoneMask: pix too small: w = 197, h = 76
$
$ cat out.txt
49612

読み取れてるー!!
エラーが出てきますが、画像の解像度(幅、高さ(px))が低い場合に出るようです。
github.com

まとめ

というわけで、あっさり画像認識ができました。
でも実際の写真に含まれる数字を抽出しようとすると…。

うまくいきません(´・ω・`)
(出力先のテキストが空っぽ…)
時間ができたら、もう少し戦ってみることにします。

Seleniumbasicで突如Google Chromeが開けなくなったら…

※2019/08/14:Windows 10の場合を追記しました

どうするか?

…ドライバを更新しましょう、という話です。

そもそもな話

Seleniumbasicとは何か?

florentbr.github.io

Seleniumはいろんな言語で使えるように横展開されています。
それのVB.NetVBAVBScript版になります。

経緯

久しぶりに Seleniumbasic でGoogle Chromeを開く処理を行ったんですが…

f:id:hrroct:20161208142719p:plain

というエラーが出ます。
はて。
プログラムは変えていないのに、なぜかエラーが出る。
IEなら問題なく開くのになぜ?

原因はドライバが古いこと、でした

Seleniumbasicのインストール先ディレクトリを見るとわかるのですが、「***driver.exe」というファイルがいくつかあります。
ブラウザはこれを使用して起動しているんですね。

私の場合はこちらでした。
「C:\Program Files\SeleniumBasic」(Windows 7)
「C:\Users\ユーザー名\AppData\Local\SeleniumBasic」(Windows 10)

Chromeのドライバもこちらにあるので、ダウンロードして置き換えましょう(以前のものはリネームする方がいいかも)。
「chromedriver.exe」という名前のファイルです。

取得先はこちら:

sites.google.com

更新すると…

元気にまた動いてくれました。
よかった…。

以上でした。

Chosenプラグインの使い方(基礎編2)

はじめに

Chosenプラグインネタ、第2弾です。
次は「発展編」とするはずが、複数選択時の場合が抜けていたので、それをまず書きます。

第1弾はこちら:
hrroct.hatenablog.com

第3弾も書きました:
hrroct.hatenablog.com

忘れていた、複数選択の場合

サンプルはこちら。
Edit fiddle - JSFiddle

jQuery 3.1.1
Chosen 1.6.2
を使用しております。

ベース

multiple属性とdata-placeholder属性が指定されているのが、単一選択時との違いです。

<select id="target" data-placeholder="Choose Some Items..." multiple>
    <option></option>
    <option value="1">1st Option</option>
    <option value="2">2nd Option</option>
    ...

選択された値を取得する

配列で取得するように揃えてみました。

// 配列で返ります
var valueList = $('#target').val();

// こちらも配列で取得してみる
var textList = [];
$('#target option:selected').each(function() {
    textList.push($(this).text());
});

値をセットする

セットする値を配列で与えればOKです。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([5,6]).trigger('chosen:updated');

値をクリアする

こちらも配列で指定します。空の配列ですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([]).trigger('chosen:updated');

選択肢を追加する

これは単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
var newOption = $('<option>').attr('value', 15).text('15th Option');
$('#target').append(newOption).trigger('chosen:updated');

有効化、無効化

これも単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
// 無効化
$('#target').prop('disabled', true).trigger('chosen:updated');
// 有効化
$('#target').prop('disabled', false).trigger('chosen:updated');

以上でした!

Cygwinにapache2をインストール(2016年11月版)

はじめに

タイトルのとおりですが…
XAMPPではなく、Apache2をCygwinに入れて、http://localhost/でアクセスできるところまでやりました。
その手順を公開します。
※今回Windowsのサービスへの登録は行っていません!

手順

Apache2のインストール

まず、インストールから。
入れているapt-cygにより、コマンドは多少違いますが…
searchall or find すれば、見つかるはずなのでそれをinstallします。

$ apt-cyg searchall apache2
$ apt-cyg install apache2

ちなみに、各ファイルの場所はこんな感じです。

ファイルの種類 場所
exeファイル /usr/sbin/httpd.exe
設定ファイル /etc/httpd/conf/httpd.conf
デフォルトのDocumentRoot /srv/www/htdocs
デフォルトのエラーログ /var/log/httpd/error_log
デフォルトのアクセスログ /var/log/httpd/access_log

この時点でやっておくべき最低限の設定は、サーバー名の変更でしょうか。
localhostでアクセスできるようにしておきます。

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
#ServerName www.example.com:80
ServerName localhost:80

Cygwinならでは、cygserverの起動

cygserverとは?

↓公式サイトに正確な情報が記載されています(英語)。
Cygserver

cygwin*.dll ではまかなえない機能を、Windowsの機能を用いて提供するプログラムらしいです。
apache2を起動するには、cygserverの機能が必要ということですね。
(浅い解説ですみません…時間の都合で先に進みます…)

cygserverデーモンを起動するには、まずは設定が必要になります。

設定ファイルを作成する

cygserver-configスクリプトを実行します。
パスが通ってない場合は "/usr/bin/cygserver-config" で。

また、途中で "Do you want to install cygserver as service?" と聞かれるので、今回は "no" で進めます。
(私の用途が、Windowsのサービスに登録するほどではないので)

$ cygserver-config
Generating /etc/cygserver.conf file

Warning: The following function requires administrator privileges!

Do you want to install cygserver as service?
(Say "no" if it's already installed as service) (yes/no) no

Further configuration options are available by editing the configuration
file /etc/cygserver.conf.  Please read the inline information in that
file carefully. The best option for the start is to just leave it alone.

Basic Cygserver configuration finished. Have fun!

"Have fun!" と言われたら、いざcygserverを起動してみましょう。

cygserverを起動する

バックグラウンドで起動します。

$ /usr/sbin/cygserver &
$ cygserver: Initialization complete.  Waiting for requests.

プロセスが立ち上がっているのを確認できたら、成功です。

$ ps | grep cygserver

Apacheの起動

下記コマンドを実行してみます。
エラーログ (/var/log/httpd/error_log) を "tail -f" しておくのをオススメします。

$ /usr/sbin/httpd -k start

私の場合は、下記エラーが表示されました。

AH01177: Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??
AH00020: Configuration Failed, exiting

"is mod_slotmem_shm loaded??" って言われたので、httpd.conf を編集します。
↓ここのコメントアウトを解除しました。

vi /etc/httpd/conf/httpd.conf
...
#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

そして、改めてApacheを起動してみると…
http://localhost/ に "It works!" が表示されました。
よかった…。

最後に

cygserverの存在は知らなかったので、いい勉強になりました。

Apacheのコマンドはヘルプを見るといろいろ載っています。
停止や再起動は↓こんな感じです。

$ /usr/sbin/httpd -h
 
$ /usr/sbin/httpd -k start
$ /usr/sbin/httpd -k stop
$ /usr/sbin/httpd -k restart

以上でした!

CSSでアイコンを作成してみた(その1)

はじめに

アイコンがほしい。作りたい。
自力で画像やSVGにてアイコンを作成できればいいのですが、私にIllustratorInkscapeのスキルはございません…。

そういえば、世間ではCSSでアイコンを作成している方がいらっしゃいます。

当初は仕組みを全然理解していませんでしたが、調べて作成するところまでやってみました。
もし使いたい方がいれば、ご自由にコピペしていってください。

こんな感じです

f:id:hrroct:20161111162954p:plain

ソースコード

下記の内容をhtmlファイルとして保存して、ブラウザで開いてみてください。
Google ChromeFirefox、IE11の最新版で確認は済んでおります。

  1. "font-size"をいじると大きさが変えられます。
  2. 色を変えるには「#c0c0c0」を差し替えてください。
<html>
    <head>
        <style type="text/css">
        <!--
.icon-building {
    display: inline-block;
    vertical-align: middle;
    font-size: 50px;
    width: 1.0em;
    height: 1.3em;
    border: 0.1em solid #c0c0c0;
    border-radius: 0.1em;
    margin: 0 0.2em;
    background:
        /* 上段窓、左から */
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.1em 0.1em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.4em 0.1em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.7em 0.1em / 0.2em 0.2em no-repeat,
        /* 中段窓、左から */
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.1em 0.4em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.4em 0.4em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.7em 0.4em / 0.2em 0.2em no-repeat,
        /* 下段窓、左から */
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.1em 0.7em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.4em 0.7em / 0.2em 0.2em no-repeat,
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.7em 0.7em / 0.2em 0.2em no-repeat,
        /* 入り口 */
        linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.3em 1.0em / 0.4em 0.3em no-repeat;
}
        //-->
        </style>
    </head>
    <body>
        <span class="icon-building"></span>
    </body>
</html>

ポイント

ここでの肝は"backgroup"と"linear-gradient"でしょう。
linear-gradientを使いつつもグラデーションせず、複数の四角形を位置をずらして作成しております。

background - CSS | MDN

linear-gradient - CSS | MDN

"linear-gradient"行を細かく説明すると、こんな感じです。

linear-gradient(to bottom, #c0c0c0, #c0c0c0) 0.1em 0.1em / 0.2em 0.2em no-repeat
                ---------------------------  -----------   ----------- ---------
                 |                            |             |           |
                 `- 上から下に向かって、同じ色でグラデーション(塗りつぶしと同義)。
                                              |             |           |
                                              `- 開始位置。"background-position"。
                                                            |           |
                                                            `- サイズ。"background-size"。
                                                                        |
                                                                        `- 繰り返し描画。"background-repeat"。

"to bottom"はデフォルト値なので、なくてもよいですが説明のためにつけています。

他にも…

こんなものも作れます。

f:id:hrroct:20161115165626p:plain

<html>
    <head>
        <style type="text/css">
        <!--
.icon-battery {
    display: inline-block;
    vertical-align: middle;
    font-size: 50px;
    width: 1.7em;
    height: 1.2em;
    margin: 0 0.2em;
    background:
        /* 電池本体(上の横線から時計回りに並べました) */
        linear-gradient(#c0c0c0, #c0c0c0) 0.0em 0.0em / 1.4em 0.1em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.4em 0.0em / 0.1em 0.2em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.4em 0.2em / 0.3em 0.1em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.6em 0.2em / 0.1em 0.5em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.4em 0.7em / 0.3em 0.1em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.4em 0.8em / 0.1em 0.2em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 0.0em 0.9em / 1.4em 0.1em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 0.0em 0.0em / 0.1em 0.9em no-repeat,

        /* 電池残量 */
        linear-gradient(#c0c0c0, #c0c0c0) 0.2em 0.2em / 0.3em 0.6em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 0.6em 0.2em / 0.3em 0.6em no-repeat,
        linear-gradient(#c0c0c0, #c0c0c0) 1.0em 0.2em / 0.3em 0.6em no-repeat;
}
        //-->
        </style>
    </head>
    <body>
        <span class="icon-battery"></span>
    </body>
</html>

最後に

ご覧の通り、比較的単純なアイコンであれば、わりと簡単に作れます。
※手間はかかりますけど…

より複雑なアイコンを作成しようとすると、疑似要素を使用する必要が出てくると思いますが…
それはまたの機会に。

デザイナーさんでなくとも、こういったアイコンが自力で作成できるのはいいですね!
画像と違って、拡大してもきれいに見えるのもポイントが高いです。

以上でした。