ETLを使って手書きの文字認識をやりたい

ETL

使用条件

会員登録を行い、ETLをDLする

binaryから画像にする

import struct
from PIL import Image, ImageEnhance
import glob, os

RECORD_SIZE = 2052

outdir = "ETL7-img/"
if not os.path.exists(outdir): os.mkdir(outdir)

files = glob.glob("ETL7/*")
fc = 0
for fname in files:
	fc = fc + 1
	print(fname)

	f = open(fname, "rb")
	f.seek(0)
	i = 0
	while True:
		i = i + 1
		s = f.read(RECORD_SIZE)
		if not s: break
		r = struct.unpack('>H2sH6BI4H4B4x2016s4x', s)
		iF = Image.frombytes('F', (64, 63), r[18], 'bit', 4)
		iP = iF.convert('L')
		code_jis = r[3]
		dir = outdir + "/" + str(code_jis)
		if not os.path.exists(dir): os.mkdir(dir)
		fn = "{0:02x}-{1:02x}{2:04x}.png".format(code_jis, r[0], r[2])
		fullpath = dir + "/" + fn
		enhancer = ImageEnhance.Brightness(iP)
		iE = enhancer.enhance(16)
		iE.save(fullpath, "PNG")
print("ok")

pickleの作成

import numpy as np
import cv2
import matplotlib.pyplot as plt
import glob
import pickle

out_dir = "./ETL7-img"
im_size = 32

save_file = out_dir + "/JapaneseHiragana.pickle"
plt.figure(figsize=(9, 17))

hiraganadir = list(range(177, 223+1))
hiraganadir.append(166)
result = []

for i, code in enumerate(hiraganadir):
	img_dir = out_dir + "/" + str(code)
	fs = glob.glob(img_dir + "/*")
	print("dir=", img_dir)

	for j, f in enumerate(fs):
		img = cv2.imread(f)
		img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
		img = cv2.resize(img_gray, (im_size, im_size))
		result.append([i, img])

		if j == 3:
			plt.subplot(11, 5, i + 1)
			plt.axis("off")
			plt.title(str(i))
			plt.imshow(img, cmap="gray")

pickle.dump(result, open(save_file,  "wb"))
plt.show

正解率 0.973809540271759 loss 0.09567940980195999

なんか出来てるっぽい

Pythonでインスタンスセグメンテーション

$ sudo apt -y install python3-six python3-wheel python3-numpy python3-grpcio python3-protobuf python3-termcolor python3-typing-extensions python3-h5py python3-markdown python3-werkzeug python3-requests-oauthlib python3-rsa python3-cachetools python3-google-auth
$ sudo apt -y install python3-numpy python3-sklearn python3-matplotlib python3-seaborn
$ sudo pip3 install -U tensorflow tensorflow_datasets
$ pip3 install pixellib
$ curl -LO https://github.com/ayoolaolafenwa/PixelLib/releases/download/1.2/mask_rcnn_coco.h5

sample2.jpegをDLしてdataフォルダに格納
https://pixellib.readthedocs.io/en/latest/Image_instance.html

import pixellib
from pixellib.instance import instance_segmentation

segment_image = instance_segmentation()
segment_image.load_model("data/mask_rcnn_coco.h5")
segment_image.segmentImage("data/sample2.jpeg", output_image_name = "image_new.jpg")

どういう仕組みなのかは理解したが、イマイチ上手くいかんな…
環境のせいか…

インスタンスマスク

インスタンスセグメンテーションは、オブジェクトの検出されたインスタンスごとにセグメンテーションマップを生成する

Mask R-CNNに学習させる
– RGBイメージ
– グランドトゥルース境界ボックス(オブジェクトの境界ボックスを示す)
– インスタンスラベル(NumObjects行1列のstringベクトル、またはNumObjects行1列の文字ベクトルのcell配列として指定)
– インスタンスマスク(バイナリマスク/多角形座標)
– 学習データの可視化

うーむ、時間があるときにやりたい…

[画像処理] アナログ画像からデジタル化する手順

1. 標本化(Sampling): ピクセル化
 L 2次元に分割する。これは離散的な点の集合に分割処理する

2. 量子化(Quantization): 画素値離散化
 L 濃度レベルを決める 色の階調の分割をどのくらいにするか

データ量
 画素数 x 濃度レベル(ビット)
 300 x 300 x 8bit(1byte) = 90000byte(90kbyte)
そのほか、ファイル名、作成日、画像の解像度、色数、圧縮の種類、その他必要なデータ

画像
RGBの3つのチャンネルがある
RGBのチャンネルに対して、8bit(256)のデータ幅を持っている
この3つのチャンネルにアルファ(透明度)を組み合わせている

なるほど
勉強すること多すぎる というか永遠に終わらんなコレ

[画像認識] 非局所平均値フィルタを実装

$ pip3 install scikit-image

元画像

非局所平均値フィルタ

import numpy as np
import matplotlib.pyplot as plt
from skimage import img_as_float
from skimage.restoration import denoise_nl_means, estimate_sigma
from skimage.util import random_noise

img = plt.imread('src/face.jpg')
original = img_as_float(img)

sigma = 0.1
noisy = random_noise(original, var=sigma**2)

sigma_est = np.mean(estimate_sigma(noisy, multichannel=True))

patch_kw = dict(patch_size=5,	# ノイズ除去のパッチサイズ 5x5
				patch_distance=6, # パッチを検索する距離 13x13 searchera
				multichannel=True)

denoise = denoise_nl_means(original, h=1.15*sigma_est, fast_mode=False, **patch_kw) # hはカットオフ

fig, ax = plt.subplots(figsize=(8, 6.5), sharex=True, sharey=True)

ax.imshow(denoise)
ax.axis('off')
ax.set_title('ノイズ除去')

fig.tight_layout()
plt.savefig('local_denoise_mangf.jpg',dpi=100)

かなり綺麗になってるのはわかります。

[Raspberry Pi]web cameraを使ってみる

ztc00 超小型ビデオカメラをUSBに接続します。

# lsusb
Bus 001 Device 004: ID 1bcf:0005 Sunplus Innovation Technology Inc. Optical Mouse
Bus 001 Device 027: ID 05e1:0b01 Syntek Semiconductor Co., Ltd
Bus 001 Device 005: ID 413c:2107 Dell Computer Corp.
Bus 001 Device 006: ID 0424:7800 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

# sudo apt-get -y install fswebcam subversion libjpeg8-dev imagemagick
# svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer
# cd mjpg-streamer; make

# sudo fswebcam sample.jpg
— Opening /dev/video0…
stat: No such file or directory

dav

あれ、認識してない、何でだろう??
ただ、ラズパイでビデオ、カメラ接続が容易にできることがわかった。
シェルで条件に合致したときにfswebcam sample.jpgを打ち込めばいいわけだ。
ほぼイメージができてきた。

Raspberry Piと小型カメラと山崎12年

Raspberry Pi3 Model B+と小型カメラを使って画像認識のアプリケーションを作りたい。

Raspberry Pi

ラズパイって思ってたより小さい。
山崎12年50mlと同じ位のサイズ。

取り敢えず以下の手順で開発していくイメージだけど行けるやろうか??
C言語トレーニング -> Raspberry Pi試作 -> Python学習 -> OpenCV学習 -> Django学習 -> 画像認識アプリケーション開発 -> Demo作成

まず、断捨離から始める。

光の性質

光は電波やマイクロ波と同じく、電磁波の一種(それぞれ波長の長さが異なる)
電磁波とは、電界と磁界から構成されいている波の事
隣同士の同位相の地点間の距離を波長λ[m]という
一秒間に進む距離の中に幾つの波長があるかを周波数f[Hz]として表す
速度をvとすると v = fλ[m/s]

### 粒子としての光(光子)
光子1個のエネルギーE[J]はその振動数V[Hz]によって決まる
E = hv = hc / λ[J]
※hはプランク定数(6.63 * 10^-34[Js])
※cは光の速度(3.0 * 10^8[m/s])
青い光子の方が波長が短く大きいエネルギーを持っている

### 光の性質
入射光の一部は反射(R)、残りは物質を透過(T)するか吸収(A)される
A + R + T = 1

光は物質中の速度v[m/s]は真空中よりも遅くなる
n = c/v … 屈折率n

光ファイバーはガラスと空気の境界面での全反射を利用して損失なく遠くまで光を伝えている

### 光源の種類
発光スペクトルとは光の色に対応した波長
白色光(赤LED, 白LED、豆電球、蛍光灯、液晶モニタ、水銀ランプ、ネオンランプ、レーザ)
※白色光でも波長は異なっている
電磁波を測定する事で対象の温度を測定

物質内に光を照射すると、光のエネルギーにより電子が起きる この電子が元の状態に戻るときに余計なエネルギーとして光を放出することがあり、それを蛍光という
蛍光灯内部では、放電を起こすことにより発生する紫外線を蛍光体に当てて可視光線を発生させている(水銀原子と熱電子を衝突させて紫外線を出す)

### 単位
放射束[W] 光束[lm] …光源からの光の強さ
放射照度[W/m^2] 照度[lux] …物体に入ってくる光の強さ
放射強度[W/sr] 光度[cd] …光源からある方向に出てくる光の強さ
放射輝度[W/sr/m^2] 輝度[cd/m^2] …光源からある方向に出てくる光の強さ

電磁界とは
「電磁界」とは、電流が流れている電線などのまわりに発⽣する「電界」と「磁界」の総称
「電磁波」とは、電界と磁界が交互に発⽣しながら空間を伝わっていく波

静電磁界は医療機器や鉄道などから
超低周波電磁界は電⼒設備や家電製品などから
中間周波電磁界は IH 調理器や電⼦タグ、電⼦商品監視装置などから
⾼周波電磁界は携帯電話など の無線機器や携帯電話基地局、TV・ラジオ放送局などから発⽣

光子は物質に衝突すると、反射、透過、吸収されるってあるけど、電磁波同士で衝突したら干渉したりしないのかね?
電磁界から電磁波が出るのはわかるけど、生活空間は電磁波だらけってこと? その辺りがいまいちイメージしにくい。
しかし、5Gとか通信のコア技術が電磁波なんで、重要なトピックには間違い無いんだが。。

ビデオカメラの技術

### 光学系
撮像レンズ、光学LPF、ダイクロイックプリズム、CFAなど多岐に弥

撮像レンズ
– 昔は異なる焦点距離を3-4本揃えターゲットに合わせて変えていた
– ズームレンズが開発
– 非球面レンズの導入により、レンズ枚数が減少

ダイクロイックプリズム
– レンズから入射した光線をRGB3色光学像に分解して結像させる光学部品

CFA
– R、G、B、それぞれのカラーフィルターをアレイ状に配置したもの

光学 LPF
– 被写体の高周波成分を落とす

マイクロレンズ
– フォトダイオードの上部にマイクロレンズを設けて光の利用率を向上する

### 撮像デバイス(CCD)
– ビデオカメラもCMOSイメージセンサを使用している

### 撮像管
– 電子ビームを偏向集束させるためにコイルアセンブリが必要
– フェースプレートは光学ガラスでできていて、内面にITOが真空蒸着で作られ、その上に光導電膜が形成される
– 撮像管内部は真空が保たれ、ヒーターで温めれた電子ビームが光導電膜を走査すると、光学像によって、光電効果で蓄積された信号電荷がITOの部分から取り出されていく

### CMOSイメージセンサ
– フォトダイオード(PD)とトランジスタで構成される
– フォトダイオードに蓄積された信号電荷は画素ごとに設けられた増幅器で増幅された後、垂直、水平のシフトレジスタで画素ごとにスイッチングされ、読み出される
※PDとは光を電気に変換する計測用デバイス
※トランジスタとは電子回路において、信号を増幅またはスイッチングすることができる半導体素子
※半導体とは導体と絶縁体の中間の電気伝導率をもつ物質

### ビデオカメラの技術展開
被写体 -> 撮像レンズ -> 光学LPF -> CFA -> 【CMOSセンサ】 -> LPF -> AGC CDS -> ADC -> 【カメラ基本回路】(デジタル信号処理) -> 高画質化・高機能化処理 -> ビューファインダ or 録画装置(VTR/DVD/半導体メモリ) or 出力回路

ビデオカメラやデジカメがネット接続できれば、画像処理のところはMLなどでリアルタイムで色々できそうやな。