解析エンジニアの自動化 blog

コツコツと自動化した方法を残す blog

C# で ASCII 文字列をソートすると良いことがありそうか確認した



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。


この記事の目次



背景・目的


テキストを行単位で配列に格納して、 for ループで配列を検索していると、どうしても大容量データだと時間がかかります。

使える時は限定的になりますが、ソートを活用して検索したい配列をひとかたまりにしてしまえば、処理の時間が削減できる気がしたので、とりあえず、 ASCII 文字列をソートした時の並び順を確認することにしました。



動作環境


Windows 7
Visual Studio 2017



プログラム

ASCII 文字列を昇順と降順にソートして、ファイルに出力する C#ソースコードを書きました。

ソースコード


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Sort_ASCII
{
    class Program
    {
        static void Main(string[] args)
        {
            // 出力用ディレクトリ
            string sDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
 
            // 出力用変数
            string originASCII = "";
            string ascendingASCII = "";
            string descendingASCII = "";
 
            // 印字可能な ASCII 文字列配列作成
            string[] ASCII = new string[] { " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~" };
 
            for(int i=0; i < ASCII.Length; i++)
            {
                originASCII += string.Format("{0,3}", ASCII[i]);
            }
 
            // 昇順ソート
            Array.Sort(ASCII);
 
            for (int i = 0; i < ASCII.Length; i++)
            {
                ascendingASCII += string.Format("{0,3}", ASCII[i]);
            }
 
            // 降順ソート
            Array.Reverse(ASCII);
 
            for (int i = 0; i < ASCII.Length; i++)
            {
                descendingASCII += string.Format("{0,3}", ASCII[i]);
            }
 
            // 出力
            File.WriteAllText(sDir + "\\" + "Sort-ASCII.txt", originASCII);
            File.AppendAllText(sDir + "\\" + "Sort-ASCII.txt", Environment.NewLine);
            File.AppendAllText(sDir + "\\" + "Sort-ASCII.txt", ascendingASCII);
            File.AppendAllText(sDir + "\\" + "Sort-ASCII.txt", Environment.NewLine);
            File.AppendAllText(sDir + "\\" + "Sort-ASCII.txt", descendingASCII);
        }
    }
}



結果

結果は図1 の通りとなりました。
上段、中段、下段の内容はそれぞれ以下の通りです。
上段:初期の並び順
中段:昇順
下段:降順

横長になってしまったので、スクロールできるようにしました。


     !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~
  '  -     !  "  #  $  %  &  (  )  *  ,  .  /  :  ;  ?  @  [  ]  ^  _  `  {  |  }  ~  \  +  <  =  >  0  1  2  3  4  5  6  7  8  9  a  A  b  B  c  C  d  D  e  E  f  F  g  G  h  H  i  I  j  J  k  K  l  L  m  M  n  N  o  O  p  P  q  Q  r  R  s  S  t  T  u  U  v  V  w  W  x  X  y  Y  z  Z
  Z  z  Y  y  X  x  W  w  V  v  U  u  T  t  S  s  R  r  Q  q  P  p  O  o  N  n  M  m  L  l  K  k  J  j  I  i  H  h  G  g  F  f  E  e  D  d  C  c  B  b  A  a  9  8  7  6  5  4  3  2  1  0  >  =  <  +  \  ~  }  |  {  `  _  ^  ]  [  @  ?  ;  :  /  .  ,  *  )  (  &  %  $  #  "  !     -  '
図1 図



コメント

このソースコードを流用することはないと思いますが、 ASCII の昇順、降順で並び順の変わり方が分かりました。

A B C などのアルファベットの並び順はおいといて、 @ や & 、 $ といった文字は覚えておいても良いでしょう。

決まった書式で書かれた文字列配列から、先頭が @ から始まる文字列だけを抽出する場合などはソートしてから検索して、 @ が検出されなくなったら、ループ脱出すれば、無駄なループを待つ必要がなくなります。

ただし、ファイル入力時間、ソート時間を考慮すると意味が無いかもしれません。



以上

【簡単一発コピペ】VBA でフォルダが無ければ作成するサブルーチンを作成する



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。


この記事の目次



背景・目的


VBA で何かアプリケーションを作ると新しくフォルダを作って、その新しいフォルダにファイルを保存したくなる事がいっぱいあります。

しかも、何故かいつもソースコードを忘れてしまっていて、いつもいつもインターネットを徘徊して調べています。

なので、簡単にですが、記事に残しておくことにしました。



動作環境


Windows 7
Excel 2010



プログラム

サブルーチン


Sub フォルダ作成(ByVal SaveDir)
    
    ' Path に使えない文字の配列作成
    使用不可 = Array(¥, /, ", <, >, ?, [, ], :, |, *)
    
    ' Path に使えない文字の代替文字
    代替文字 = "-"
    
    ' Path に使えない文字の置換
    For i = LBound(使用不可) To UBound(使用不可)
        If InStr(SaveDir, 使用不可(i)) > 0 Then
            SaveDir = Replace(SaveDir, 使用不可(i), 代替文字)
        End If
    Next i
    
    ' SaveDir フォルダがなければ作成する
    ' SaveDir の中身は ex) みたいな感じです
    ' ex) SaveDir = "C:\Data\Sample"
    ' 最後に「 \ 」は付けない
    If Dir(SaveDir, vbDirectory) = "" Then
        MkDir SaveDir
    End If
    
End Sub



使い方

今回は VBA が書かれている Excel ファイルと同じフォルダの中に大量にフォルダを作る VBA を例に使い方を整理しておきます。

図1 の様にExcel ファイルの A 列に作成したいフォルダ名を入力します。


図1 作成フォルダ設定


そして、 VBE に標準モジュールを追加して、下記の Excel VBA を貼り付けます。

ちなみに、 VBE は [Alt] + [F11] を押すと起動ます。

また、標準モジュールは VBE がアクティブな時に [Alt] → [I] → [M] の順で押すと追加できます。

Excel VBA


Sub Sample()
    
    While Cells(i, "A").Value <> ""
        
        sDir = Thisworkbook.Path & "¥" & Cells(i, "A").Value
        
        Call フォルダ作成(sDir)
        
    Wend
    
End Sub

Sub フォルダ作成(ByVal SaveDir)
    
    使用不可 = Array(¥, /, ", <, >, ?, [, ], :, |, *)
    代替文字 = "-"
    For i = LBound(使用不可) To UBound(使用不可)
        If InStr(SaveDir, 使用不可(i)) > 0 Then
            SaveDir = Replace(SaveDir, 使用不可(i), 代替文字)
        End If
    Next i
    
    If Dir(SaveDir, vbDirectory) = "" Then
        MkDir SaveDir
    End If
    
End Sub


これで、準備は出来ました。
あとは、「Sample」マクロを実行すれば、この Excel ファイルがあるフォルダと同じ場所に Excel ファイルの A 列に書かれたフォルダが量産されます。

マクロの実行は [Alt] + [F8] を押すと選択画面が開きます。
そこで、「Sample」をダブルクリックすれば実行できます。



コメント

忘れたら見に来てください。



以上

winpython(Flask) で Web アプリケーション入門



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。


この記事の目次



背景・目的


何か Web アプリケーションを作ってみたい気はしていたのですが、アイデアばかりを考えてしまって、サーバー借りたり、セキュリティだったりのめんどくさい事になかなか踏み切らないでいたら、 heroku という PaaS を何でか知り得たので、今後を見据えて、勢いで Web フレームワークの Flask をとりあえずいじってみる。



動作環境


Windows 7
・winpython 3.4.4
・Flask は winpython に同梱されていたものも使用しました。



プログラム

サーバーにアクセスすると、

Hello World !
改行テスト

と表示されるプログラムを作ります。

ソースコード


# Flask のインポート
from flask import Flask
 
# アプリケーションのインスタンス作成
app = Flask(__name__)
 
# アプリケーションのルートにアクセスしたときの処理
@app.route('/')
def hello_world():
    return "Hello World !<br>改行テスト"
 
# __name__ が __main__ だったら
if __name__ == '__main__':
    app.run()



結果

winpython は F5 キーでプログラム実行出来ます。
実行すると以下のようなメッセージが出てきます。
なお、このプログラムは下記メッセージにもあるように Ctrl + C を押すまで実行し続けます。

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

なんでもいいので、IE ブラウザを立ち上げて、 URL の入力欄に http://127.0.0.1:5000/ と入力して自分のパソコンにポート番号 5000 使ってアクセスします。

すると、図1 の様に表示されます。


図1 図 実行画面


Ctrl + C を押して、プログラムの実行を終了する事を忘れずに!!



コメント

レベルとしては Web アプリケーションとはいかないですが、 python で Flask を使ってみることに成功しました。

これを皮切りに Flask で Web アプリケーションを作成して、デプロイ(公開)してみたくなりました。



以上

Python + pyocr で ocr したら高認識率で1桁数字も認識した



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。



この記事の目次



目的


今まで Tesseract を使用して ocr してきました。
この際、 pytesseract という Python から Tesseract を使うためのライブラリを使っていました。

しかし、私のソースコードや操作が悪かったのかもしれませんが、1桁の数字を認識出来ないという問題がありました。

そこで、pyocr という Python から Tesseract を使うためのライブラリを使って ocr してみます。



プログラム

ソースコード


# -*- coding: utf-8 -*-
###############################################################################
# ライブラリインポート
###############################################################################
import os                       # os の情報を扱うライブラリ
from PIL import Image           # 画像処理ライブラリ
import matplotlib.pyplot as plt # データプロット用ライブラリ
import numpy as np              # データ分析用ライブラリ
import pyocr                    # OCR ラッパーライブラリ 対応OCR:Tesseract, Cuneiform
import pyocr.builders           # OCR ラッパーライブラリ 対応OCR:Tesseract, Cuneiform
import sys                      # 実行環境関連ライブラリ
 
# カレントディレクトリを変更する
os.chdir("C:\\作業\ocr-Preprocessing")
 
Image000 = '000_Const_Image.jpg'
 
tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
 
tool = tools[0]
 
#################### 画像の読み込み ####################
img = Image.open(Image000)
 
txt = tool.image_to_string(
        img,
        lang="eng",
        builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
 
# 画像を配列に変換
im_list = np.array(img)
 
# データプロットライブラリに貼り付け
plt.imshow(im_list)
 
# 表示
plt.show()
 
# 抽出したテキストの出力
print()
print("text ↓")
print(txt)
print()



画像処理の結果

図1 は WinPython の実行画面、図2 は入力画面と認識文字の比較図です。


図1 WinPython の実行画面


図3 入力画面と認識文字の比較図



コメント

今まで1桁の数字の ocr にすごく苦戦していたのですが、あっさり全部正確に認識しました。

今まで Python + pytesseract では全然認識しなかったのに。

出来るときはこんなものですよね。

資料のデータベースを作成する時に数字の読み取りは必須なので、データベース作成プログラムでも作ってみたいです。



以上

【 ocr の認識率を上げる画像処理】初心者でも簡単な補間



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。



この記事の目次



目的


補間はノイズ除去の一種だと思います。

ノイズ除去では文字周りに小さな点が散らばっていました。

しかし、いつも文字の周りにあるとは限りません。
文字の中にも小さな点が入り込む事があります。
この記事では、この入り込んだノイズを除去する処理をまとめます。

今回もノイズ除去と同じ様に PythonOpen CV を使って、すごく簡単に補間をやってみます。

収縮、膨張処理を行うので、画像はあらかじめ二値化されていること。また、処理したい線が白であることが必要です。

やり方としては膨張処理を行ってから収縮処理を行うだけです。

ノイズ除去と逆の順番で処理を行うだけです。

今回は Open CV にもともと収縮処理の後に膨張処理を行うメソッドがあるので、そのメソッドを使いますが、自分で膨張処理の後に収縮処理を行うソースコードを書いても出来ます。

ノイズ除去はリンクの記事でまとめています。

【 ocr の認識率を上げる画像処理】初心者でも簡単なノイズ除去 - 解析エンジニアの自動化 blog

また、膨張処理と収縮処理はリンクの記事でまとめています。
なお、リンクの記事で二値化と白黒反転処理もさせているので、参考にしてみてください。

【 ocr の認識率を上げる画像処理】画像をキレイにする基本〜膨張処理〜 - 解析エンジニアの自動化 blog

【 ocr の認識率を上げる画像処理】画像をキレイにする基本〜収縮処理〜 - 解析エンジニアの自動化 blog



プログラム

ソースコード


# -*- coding: utf-8 -*-
###############################################################################
# ライブラリインポート
###############################################################################
import os                       # os の情報を扱うライブラリ
import pytesseract              # tesseract の python 用ライブラリ
from PIL import Image, ImageOps # 画像処理ライブラリ
import numpy as np              # データ分析用ライブラリ
import cv2                      # OpenCV ライブラリ
 
# 白黒反転関数
def ColorInverter(img):
    img.convert('RGB')
    Inv_img = ImageOps.invert(img)
    return Inv_img
 
# 補間(膨張⇒収縮)
def Interpolation(img):
    kernel = np.ones((2, 2))
    Close_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
    return Close_img
 
# カレントディレクトリを変更する
os.chdir("C:\\作業\ocr-Preprocessing")
 
# ファイル名定義
Image000 = '000_Crack_On_Const_Image.jpg'
Image005 = '005_Inv_Crack_On_Const_Image.jpg'
Image010 = '010_CleanUp_Crack_On_Const_Image.jpg'
 
# pytesseract に tesseract のパスを通す
pytesseract.tesseract_cmd='C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
 
#################### 画像の読み込み ####################
img = Image.open(Image000)
 
# 白黒反転
Inv_img = ColorInverter(img)
Inv_img.save(Image005)
 
#################### 画像の読み込み ####################
img = cv2.imread(Image005, 0)
 
# 補間(膨張⇒収縮)
CleanUp_img = Interpolation(img)
cv2.imwrite(Image010, CleanUp_img)



画像処理の結果

図1 は入力画像、図2 は二値化・白黒反転画像、図3 は補間画像です。


図1 入力画像



図2 二値化・白黒反転画像


図3 補間画像



コメント

図1 と図2 の文字の中にある点々のノイズが図3 にはありません。

文字の欠けていた部分が、補間されています。

文字の中に入り込んでいるノイズの除去とも言えます。

この方法はプログラムがノイズを認識しているわけではないので、使い方には注意が必要です。



以上

【 ocr の認識率を上げる画像処理】初心者でも簡単なノイズ除去



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。



この記事の目次



目的


ノイズ除去は最も重要な画像処理だと思っています。

今でこそ Python などでライブラリを簡単に使えて誰でもノイズ除去出来ますが、よりキレイで鮮明な画像を追い求めたら、難しさを極めると思います。

でも、この記事では PythonOpen CV を使って、すごく簡単にノイズ除去をやってみます。

収縮、膨張処理を行うので、画像はあらかじめ二値化されていること。また、処理したい線が白であることが必要です。

やり方としては収縮処理を行ってから膨張処理を行うだけです。
今回は Open CV にもともと収縮処理の後に膨張処理を行うメソッドがあるので、そのメソッドを使いますが、自分で収縮処理の後に膨張処理を行うソースコードを書いても出来ます。

膨張処理と収縮処理はリンクの記事でまとめています。
なお、リンクの記事で二値化と白黒反転処理もさせているので、参考にしてみてください。

【 ocr の認識率を上げる画像処理】画像をキレイにする基本〜膨張処理〜 - 解析エンジニアの自動化 blog

【 ocr の認識率を上げる画像処理】画像をキレイにする基本〜収縮処理〜 - 解析エンジニアの自動化 blog



プログラム

ソースコード


# -*- coding: utf-8 -*-
###############################################################################
# ライブラリインポート
###############################################################################
import os                       # os の情報を扱うライブラリ
import pytesseract              # tesseract の python 用ライブラリ
from PIL import Image, ImageOps # 画像処理ライブラリ
import numpy as np              # データ分析用ライブラリ
import cv2                      # OpenCV ライブラリ
 
# 白黒反転関数
def ColorInverter(img):
    img.convert('RGB')
    Inv_img = ImageOps.invert(img)
    return Inv_img
 
# ノイズ除去(収縮⇒膨張)
def NoiseRemoval(img):
    kernel = np.ones((2, 2))
    Open_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    return Open_img
 
# カレントディレクトリを変更する
os.chdir("C:\\作業\ocr-Preprocessing")
 
# ファイル名定義
Image000 = '000_Noise_On_Const_Image.jpg'
Image005 = '005_Inv_Noise_On_Const_Image.jpg'
Image010 = '010_CleanUp_Noise_On_Const_Image.jpg'
 
# pytesseract に tesseract のパスを通す
pytesseract.tesseract_cmd='C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
 
#################### 画像の読み込み ####################
img = Image.open(Image000)
 
# 白黒反転
Inv_img = ColorInverter(img)
Inv_img.save(Image005)
 
#################### 画像の読み込み ####################
img = cv2.imread(Image005, 0)
 
# ノイズ除去(収縮⇒膨張)
CleanUp_img = NoiseRemoval(img)
cv2.imwrite(Image010, CleanUp_img)



画像処理の結果

図1 は入力画像、図2 は二値化・白黒反転画像、図3 はノイズ除去画像です。


図1 入力画像



図2 二値化・白黒反転画像


図3 ノイズ除去画像



コメント

図1 と図2 にあった点々のノイズが図3 にはありません。

ノイズが除去出来ています。

ただ、文字の線の太さとノイズの大きさが同じくらいだと、この手法は通用しないので、要注意です。



以上

【 ocr の認識率を上げる画像処理】画像をキレイにする基本〜収縮処理〜



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。



この記事の目次



目的


白色を収縮させて輪郭を小さくする収縮処理というものがあって、収縮処理単体で行うことは少ないが、膨張処理と併用されることでノイズ除去や補間をする事が出来る基本処理として有名な処理です。

この処理は白色を対象に処理されるので、前提として、画像が二値化されていること。また、処理したい線が白であることが必要です。

二値化と白黒反転はリンクの記事でまとめています。
この記事では、収縮処理についてまとめます。

【画像処理】 ocr に必要な色々な画像処理を見据えた白黒反転処理 - 解析エンジニアの自動化 blog



プログラム

ソースコード


# -*- coding: utf-8 -*-
###############################################################################
# ライブラリインポート
###############################################################################
import os                       # os の情報を扱うライブラリ
import pytesseract              # tesseract の python 用ライブラリ
from PIL import Image, ImageOps # 画像処理ライブラリ
import numpy as np              # データ分析用ライブラリ
import cv2                      # OpenCV ライブラリ
 
# 白黒反転関数
def ColorInverter(img):
    img.convert('RGB')
    Inv_img = ImageOps.invert(img)
    return Inv_img
 
# 収縮処理関数
def ErosionImageByCV2(img):
    kernel = np.ones((2, 2))
    Ero_img = cv2.erode(img, kernel, iterations = 1)
    return Ero_img
 
# カレントディレクトリを変更する
os.chdir("C:\\作業\ocr-Preprocessing")
 
# ファイル名定義
Image000 = '000_Const_Image.jpg'
Image005 = '005_Inv_Const_Image.jpg'
Image010 = '010_Erosion_Const_Image.jpg'
 
# pytesseract に tesseract のパスを通す
pytesseract.tesseract_cmd='C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
 
#################### 画像の読み込み ####################
img = Image.open(Image000)
 
# 白黒反転
Inv_img = ColorInverter(img)
Inv_img.save(Image005)
 
#################### 画像の読み込み ####################
img = cv2.imread(Image005, 0)
 
# 収縮処理
Erosion_img = ErosionImageByCV2(img)
cv2.imwrite(Image010, Erosion_img)



画像処理の結果

図1 は入力画像、図2 は二値化・白黒反転画像、図3 は収縮画像です。


図1 入力画像



図2 二値化・白黒反転画像


図3 膨張画像



コメント

図3 の収縮画像は図2 の二値化・白黒反転画像より、輪郭が小さくなっています。

白色の線が細過ぎた場合、文字が消えちゃうかもしれませんね。



以上