[画像認識] MNISTによる手書き文字の認識

手書き文字認識はMNISTのデータセットを使って、keras, kaggleからデータを取り込むことができる。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

mnist = tf.keras.datasets.mnist.load_data()
train, test = mnist
(x_train, y_train),(x_test, y_test) = mnist

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

(60000, 28, 28) // 28x28pxのデータが60000枚
(60000,)
(10000, 28, 28) // 28x28pxのデータが10000枚
(10000,)

データセットを画像で確認

print(x_train[0])

plt.imshow(x_train[0])
plt.savefig('image.jpg',dpi=100)

### モデルの作成

x_train = x_train / 255.0  # 0-1の間に抑えるよう正規化する
x_test = x_test / 255.0

# Sequential(系列)モデル構築 インスタンスにリストを追加する
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Input((28, 28))) # 入力層は28x28
model.add(tf.keras.layers.Flatten()) # 一元配列1, 784 に変換

# 入力層から情報を受け継いで計算を行う中間層
model.add(tf.keras.layers.Dense(128)) # 128個に全結合
model.add(tf.keras.layers.Activation(tf.keras.activations.relu)) # 中間層の活性化関数の設定, reluは0以下は0、0以上は入力値を出力
model.add(tf.keras.layers.Dropout(0.2)) # 過学習を防ぐため20%ドロップアウト

# 出力
model.add(tf.keras.layers.Dense(10)) # 出力層0~9の10個
model.add(tf.keras.layers.Activation(tf.keras.activations.softmax)) # softmax関数は出力値の合計が100%になる

# コンパイル
model.compile(
	optimizer=tf.keras.optimizers.Adam(), # optimizerは逆伝播モジュール 手本と出力を比較して重みw, バイアスbを修正, AdamはAdaptive Moment Estimationの略でmomentumSGDとRMSpropを合わせたアルゴリズム
	loss=tf.keras.losses.sparse_categorical_crossentropy, # 誤差関数モジュール 正解値と予想値のズレを計算
	metrics=[tf.keras.metrics.sparse_categorical_accuracy] # 評価関数
)

# fitで学習 epochsで5回
model.fit(x_train, y_train, epochs=5)

print(model.evaluate(x_test, y_test))

plt.imshow(x_test[0])
plt.savefig('data/test_img.jpg',dpi=100)

# predict
pred = model.predict(x_test[0][np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


img = Image.open("data/handwriting.jpg").convert('L')
img.thumbnail((28, 28))
img = np.array(img)
pred = model.predict(img[np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


[0.0724998340010643, 0.9782000184059143]
7
3

ほう

[tesseract] 免許証の文字を読み込みたい : tesseract_layoutの検証

免許証画像は以下を使用する

tesseract_layoutの値を1から10まで変更して検証する

### tesseract_layout=1
$ python3 main.py
(mm| 日 本 花 子 軌和61年 5月

]1 日生

人誠| 東京都生代田区霞が関2ー 1一2
け| 令和01年05807H 12345

### tesseract_layout=2
$ python3 main.py
Traceback (most recent call last):
File “main.py”, line 9, in
txt = tools[0].image_to_string(
File “/home/vagrant/.local/lib/python3.8/site-packages/pyocr/tesseract.py”, line 386, in image_to_string
raise TesseractError(
pyocr.error.TesseractError: (-1, “Unable to find output file (tested [‘/tmp/tmpuiijvfgx/output.txt’])”)

### tesseract_layout=3
$ python3 main.py
(mm| 日 本 花 子 軌和61年 5月

]1 日生

人誠| 東京都生代田区霞が関2ー 1一2
信和01年05』07H 12345

### tesseract_layout=4
$ python3 main.py
(名| 日 本 花 子 昭和61年 5月 1日生

人誠| 東京都生代田区霞が関2ー 1一2
交付| 令和O1年05』07H 12345

2024箇(06$06有O1Hまで勧

%の 眼鏡等
条件等

見 本
き引第 012345678900 号

0
を人 ト民捧人構誠還| 〇〇OOO
=層衣2908』018導笛にに回較固 ま中

### tesseract_layout=5
$ python3 main.py
| |
に 5
中 M
加 9
9
避 Ok
ら 呈較っ
守 CN OS
| 較 抽| |睦旧旧計員
ー|。居 則遇|
| mp
– 還 RE 逢遇
| | 国~園 必g式還
玲|上 O、 は半較|
陸中 8
| 錠 [壮 加|
| 略叶RS sss
是 陸中
| 還|二 地
| 層間 ら5 8さき
EE ーーベ
[es = 絆|還> 証庄計
首日 EHP

### tesseract_layout=6
$ python3 main.py
(信所| 東京都寺代田区霞が関2-1一2

$和01キ05』07B 12345

天の 眼鏡等 に

条件等

見本 *

*引012345678900 呈 叶

に天上1 5404』01H話司にに放還 ま
に17108801間 汗天市生天 )
にafW29*08801 只間四時間 Sgms 583

### tesseract_layout=7
$ python3 main.py
で 敵 ーー an

### tesseract_layout=8
$ python3 main.py
で 敵

### tesseract_layout=9
$ python3 main.py
|

### tesseract_layout=10
$ python3 main.py
er

### 結論
tesseract_layout=4, lang=’jpn’ が一番まともな気がするけど、
なんでだろう?
きちんと精度高く読み取るにはGoogleのVison APIで実装するっぽいな…

[beautifulsoup4] aタグの中身を取得

# -*- coding: utf-8 -*-
from urllib.request import urlopen
from bs4 import BeautifulSoup
from pprint import pprint

URL = 'https://news.yahoo.co.jp/'
with urlopen(URL) as res:
	html = res.read().decode("utf-8")

soup = BeautifulSoup(html, 'html.parser')

titles = soup.select('.sc-esjQYD a')
titles = [t.contents[0] for t in titles]

pprint(titles)

$ python3 title.py
[‘東京で新たに409人の感染確認’,
‘総務相 NTTと会食有無答えず’,
‘変異株 仏で新規感染の7割に’,
‘変異株感染で死亡判明 大阪’,
‘うつぶせ寝で1歳死亡 和解’,
‘ワタミ、労基署から是正勧告’,
‘ワタナベマホト容疑者逮捕’,
‘森本選手「驚いたから」供述’]

で、これを適正開示でやる

$ python3 title.py
[’16:30 36320グリー 特別利益(投資有価証券売却益)の計上(見込み)に関するお知らせ’,
’16:30 37190J-ジェクシード 代表取締役の異動に関するお知らせ’,
’16:30 41740J-アピリッツ 2021年1月期決算短信〔日本基準〕(非連結)’,
’16:30 45990M-ステムリム レダセムチドの慢性肝疾患を対象とした医師主導治験(第2相試験)の第一例目投与に関するお知らせ’,
’16:30 50110ニチレキ 行使価額修正条項付新株予約権の大量行使に関するお知らせ’,
’16:30 67720コスモス電 ‘
// 省略

うーむ、、、cronでメール送信したい。

バッチで走らせる時間にリリースされた開示情報のみ送信したいなー
dateで分岐やな

[CentOS8] beautifulsoup4を使おう

$ python3 –version
Python 3.6.8
$ pip3 –version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
$ sudo pip3 install beautifulsoup4
$ sudo pip3 install requests
$ sudo pip3 install lxml

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup

target_url = 'https://kakaku.com/pc/note-pc/itemlist.aspx?pdf_ob=0'
r = requests.get(target_url)
soup = BeautifulSoup(r.text, 'lxml')

for a in soup.find_all('a'):
      print(a.get('href'))

[tesseract4.1.1] Ubuntuにtesseract(Eng、日本語、簡体字中国語、繁体字中国語、スペイン語)を入れよう

1. PPA(パーソナル・パッケージ・アーカイブ)を追加
$ sudo add-apt-repository ppa:alex-p/tesseract-ocr
$ sudo apt-get update

2. Tesseractインストール
$ sudo apt install tesseract-ocr
$ sudo apt install libtesseract-dev

$ tesseract -v
tesseract 4.1.1-rc2-25-g9707
$ tesseract –list-langs
List of available languages (2):
eng
osd

3. 日本語、簡体字中国語、繁体字中国語、スペイン語をインストール
$ sudo apt install tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract-ocr-spa
$ tesseract –list-langs
List of available languages (6):
chi_sim
chi_tra
eng
jpn
osd
spa

4. pyocr install
$ pip install pyocr

5. 中国語の画像を読み取る

$ tesseract chinabank.jpeg output -l chi_sim
中国平安
PINGAN

保险’ 银行. 投资

6. pythonで書く

from PIL import Image
import sys
import pyocr

tools = pyocr.get_available_tools()
langs = "chi_sim"

img = Image.open('images.jpeg')
txt = tools[0].image_to_string(
		img,
		lang=langs,
		builder=pyocr.builders.TextBuilder(tesseract_layout=6)
	)
print(txt)

$ python app.py
中国平安
PINGAN
保险; 银行.投资

さて、これをDjangoで実装したい。
思ったより考えるの難しいな。

PythonでCSVを出力したい

DjangoでCSVを出力したいのですが、まずはlocalでpythonで試します。

– encodingを付けないと文字化けするので注意が必要

import csv

file = open('new.csv', 'w', newline='', encoding='utf_8_sig')
w = csv.writer(file)
w.writerow([2191,'テラ',851])
w.writerows([[4563,'アンジェス',1435],[3911,'Aiming',693],[3776,'ブロードバンドタワー',384]])

file.close()

$ python test.py

writerowをforループで良さそうです。これをDjangoで実装します。

Pythonで今月、前月、来月、昨年、毎月あたりを取得する

### 今日
まず本日から

from datetime import datetime, date, timedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d'))

$ python test.py
2020-10-10

#### 今年、今月、来月、前月

from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d')) # 今日

print(today.year) # 今年
print(today.month) # 今月

next_month = today + relativedelta(months=1)

print(next_month.year) # 来月
print(next_month.month) # 来月

one_month_before = today - relativedelta(months=1)

print(one_month_before.year) # 前月
print(one_month_before.month) # 前月

$ python test.py
2020-10-10
2020
10
2020
11
2020
9

前月や翌月など月ごとの計算はtimedeltaではできないらいしいので、relativedeltaを使うと良いらしい。
月単位で計算できるrelativedeltaはかなり使えますね。

### Python学習でオススメの本
掌田 津耶乃の本は勉強になります。

Pythonでqrコードを作りたい

QRコード画像生成ライブラリ「qrcode」をインストールします。

$ pip install qrcode
$ pip install pillow

### テキストを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('test text')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

### URLを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('https://www.google.com/')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

アラ? 凄い簡単に出来ますね。。。簡単過ぎてビックリした。

Python & reportlab でPDF見積書を作成

pythonでPDFの見積書を作っていきます。
reportlabでテーブルではなくテキスト配置で右寄せがわからないのが脛に傷。

# -*- coding: utf-8 -*-

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.lib.pagesizes import A4, portrait
from reportlab.platypus import Table, TableStyle
from reportlab.lib.units import mm
from reportlab.lib import colors


def make(filename="estimate"): # ファイル名
    pdf_canvas = set_info(filename) # キャンバス名
    print_string(pdf_canvas)
    pdf_canvas.save() # 保存

def set_info(filename):
	pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename))
	pdf_canvas.setAuthor("hpscript")
	pdf_canvas.setTitle("見積書")
	pdf_canvas.setSubject("見積書")
	return pdf_canvas

def print_string(pdf_canvas):
	# フォント登録
	pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))

	width, height = A4

	# 見積日
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(440, 810, '見積日: 2020年10月1日')

	# title
	font_size = 24
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(245, 770, '御 見 積 書')

	# 線
	pdf_canvas.line(50, 750, 550, 750)

	# 宛先
	font_size = 14
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(60, 710, '六本木ソフトウェア株式会社 御中')
	pdf_canvas.drawString(60, 690, '営業部  山田太郎 様')

	# 線
	pdf_canvas.line(50, 680, 350, 680)

	# 注釈
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(190, 670, '下記の通りお見積もり申し上げます。')

	# 納期、支払条件、有効期限
	font_size = 12
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(100, 635, '納期:')
	pdf_canvas.drawString(200, 635, '別途ご相談')
	pdf_canvas.line(200, 633, 350, 633)

	pdf_canvas.drawString(100, 615, '支払い条件:')
	pdf_canvas.drawString(200, 615, '月末締め翌月末払い')
	pdf_canvas.line(200, 612, 350, 612)

	pdf_canvas.drawString(100, 595, '有効期限:')
	pdf_canvas.drawString(200, 595, 'お見積り後2週間')
	pdf_canvas.line(200, 593, 350, 593)

	# 自社情報
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(360, 680, '丸の内ソフトウェア株式会社')
	pdf_canvas.drawString(360, 670, '〒100-0001')
	pdf_canvas.drawString(360, 660, '東京都千代田区千代田1-1-1')
	pdf_canvas.drawString(360, 645, 'TEL: 03-1234-5678')
	pdf_canvas.drawString(360, 635, 'E-mail: info@marunouchi-soft.com')
	pdf_canvas.drawString(360, 625, '担当: 田中一郎')

	# 合計金額
	font_size = 14
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(80, 550, '合計金額')
	pdf_canvas.drawString(180, 550, '800,000 円 (税込)')

	# 線
	pdf_canvas.line(50, 540, 350, 538)

	# 分類、型番、品名、規格寸法、基準単価
	data = [
		['分類', '型番','品名', '規格寸法','数量','基準単価'],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
		[' ',' ',' ',' ',' '],
	]
	table = Table(data, colWidths=(25*mm, 25*mm, 55*mm, 25*mm, 15*mm,30*mm), rowHeights=7.5*mm)
	table.setStyle(TableStyle([
			('FONT', (0, 0), (-1, -1), 'HeiseiKakuGo-W5', 8),
			('BOX', (0, 0), (-1, -1), 1, colors.black),
			('INNERGRID', (0, 0), (-1, -1), 1, colors.black),
			('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
		]))
	# table.wrapOn(pdf_canvas, 20*mm, 20*mm)
	table.wrapOn(pdf_canvas, 20*mm, 20*mm)
	table.drawOn(pdf_canvas, 18*mm, 100*mm)

	# 小計、消費税、合計
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(360, 250, '小計:')
	pdf_canvas.drawString(450, 250, '700000円')
	pdf_canvas.line(360, 245, 550, 245)	

	pdf_canvas.drawString(360, 230, '消費税:')
	pdf_canvas.drawString(450, 230, '70000円')
	pdf_canvas.line(360, 225, 550, 225)	

	pdf_canvas.drawString(360, 210, '合計:')
	pdf_canvas.drawString(450, 210, '770000円')
	pdf_canvas.line(360, 205, 550, 207)	

	# 宛先
	font_size = 9
	pdf_canvas.setFont('HeiseiKakuGo-W5', font_size)
	pdf_canvas.drawString(60, 175, '備考')

	pdf_canvas.rect(50, 50, 500, 120)



	pdf_canvas.showPage()
	
if __name__ == '__main__':
	make()

$ python estimate.py

OK、これをDjangoに組み込みたい。この関数はviews.pyに書くけば良いのか???

Python&reportlabでPDFを生成2

# -*- coding: utf-8 -*-

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
import reportlab.lib.colors as color

def make(filename="test"):
	pdf_canvas = set_info(filename)
	print_string(pdf_canvas)
	# print_figure(pdf_canvas)
	# print_line(pdf_canvas)
	pdf_canvas.save()

# 初期設定
def set_info(filename):
	pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename), bottomup=False) # 原点は左上

	pdf_canvas.setAuthor("hpscript")
	pdf_canvas.setTitle("make pdf using reportlab")
	pdf_canvas.setSubject("reportlab")

	return pdf_canvas


# 文字
def print_string(pdf_canvas):
	pdfmetrics.registerFont(UnicodeCIDFont("HeiseiKakuGo-W5"))
	pdfmetrics.registerFont(UnicodeCIDFont("HeiseiMin-W3"))

	pdf_canvas.setFont("HeiseiKakuGo-W5", 15)
	pdf_canvas.drawString(50, 50, "日経平均レバレッジ上場投信")

	pdf_canvas.setFont("HeiseiMin-W3", 30)
	pdf_canvas.drawString(300, 100, "日経ダブルインバース上場投信")

if __name__ == '__main__':
	make()

$ python test.py

いけますね、なんとなく掴みました。
続いて図形

def print_line(pdf_canvas):
	pdf_canvas.rect(50, 150, 200, 250)

	pdf_canvas.setFillColor(color.blue)
	pdf_canvas.circle(400, 350, 50, stroke=False, fill=True)

# 線
def print_line(pdf_canvas):
	# 普通の線
	pdf_canvas.line(50, 450, 500, 450)

	# 赤い太い線
	pdf_canvas.setStrokeColor(color.red)
	pdf_canvas.setLineWidth(10)
	pdf_canvas.line(100, 500, 550, 500)

	# 破線
	pdf_canvas.setStrokeColor(color.black)
	pdf_canvas.setLineWidth(5)
	pdf_canvas.setDash([2, 8, 5, 10])
	pdf_canvas.line(150, 550, 600, 550)

	# 複数の線
	pdf_canvas.setLineWidth(1)
	pdf_canvas.setDash([])
	lines = [(100, 650, 200, 750),(200, 750, 300, 650),(300, 650, 300, 750),(100, 700, 400, 700)]
	pdf_canvas.lines(lines)

OK^^