このデモでは、ブラウザ上で動作するAI(TensorFlow.js)が、あなたが書いた数字をリアルタイムで解析しています。以下、実装された精度向上のための技術的処理を詳しく説明します。
描画されたキャンバスから、数字が書かれている領域を高精度に検出するため、2段階投影法を採用しています。
ステップ1: 行の検出(Y軸投影)
まず、画像全体を上から下にスキャンし、各行におけるインク(黒いピクセル)の量を集計します。インクが存在する連続した領域を1つの「行」として認識することで、複数行にわたって数字が書かれた場合でも正確に分離できます。
ステップ2: 列の検出(X軸投影)
次に、検出された各「行」の中で、今度は左から右にスキャンし、縦方向のインク分布を調べます。これにより、横に並んだ複数の数字を1文字ずつ分離します。
ステップ3: タイトクロップ(最小矩形抽出)
検出された領域内で、実際にインクが存在する最小の矩形を算出します。これにより、余白やノイズを徹底的に除去し、文字の輪郭のみを正確に切り出すことができます。このタイトクロップ処理は、後続の前処理における歪みを最小化するために極めて重要です。
ステップ4: 自然な読み順の保証
最後に、検出されたすべての文字領域を「上から下、左から右」の順にソートすることで、人間が読む自然な順序でAIに入力されるよう調整しています。
切り出した各文字画像を、AIが学習したMNISTデータセット形式に合わせるため、以下の厳密な前処理を行います。
色空間の変換と反転
まず、グレースケール化した後、色を反転します(白背景の黒文字 → 黒背景の白文字)。これは、MNISTデータセットが黒背景に白文字で構成されているためです。この反転処理により、学習データとの色分布の整合性を保ちます。
アスペクト比を保持したリサイズ
文字の縦横比を維持したまま、長辺が20ピクセルになるようリサイズします。これにより、縦長の「1」や横長の「8」など、元の形状を損なわずに縮小できます。単純に28x28に引き伸ばすと文字が歪み、認識精度が大幅に低下するため、このステップは必須です。
中央パディング
リサイズした画像を28x28のキャンバスの中央に配置するため、上下左右に均等にパディング(黒い余白)を追加します。MNISTの学習データも同様に中央配置されているため、この処理により位置ずれによる誤認識を防ぎます。
左下の「INPUT」プレビューが、これらの前処理を経て実際にAIに入力されている画像です。
畳み込みニューラルネットワーク(CNN)という深層学習技術を用いて、前処理済みの28x28画像から数字を判定します。
CNNは、画像内の局所的な特徴(エッジ、曲線、交点など)を段階的に抽出し、それらを組み合わせることで「0〜9のどの数字である確率が最も高いか」を計算します。モデルは各数字に対して0〜1の確率スコアを出力し、その中で最大値を持つ数字が最終的な認識結果となります。
このような多段階の精度向上処理により、手書きの揺らぎや個人差があっても、高い認識率を実現しています。