{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Read first\n\nSorry, I use Japanese here.\n\nBecause, I can't speak English.\n\n日本語で書きます。  \nこのカーネルは不十分な箇所がある可能性があるので、何か指摘があればコメントください。\n\n\n[https://www.kaggle.com/anokas/kuzushiji-visualisation/output](https://www.kaggle.com/anokas/kuzushiji-visualisation/output)\nここを参考にしました"},{"metadata":{},"cell_type":"markdown","source":"ここではtrainデータから文字を抽出して保存します。\n\nここで保存したデータを使って文字の識別モデルを作成することもできるはず（？）です。"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"from PIL import Image, ImageDraw, ImageFont\nfrom os import listdir\nfrom glob import glob\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/train.csv')\nunicode_map = {codepoint: char for codepoint, char in pd.read_csv('../input/unicode_translation.csv').values}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fontsize = 50\n# From https://www.google.com/get/noto/\n!wget -q --show-progress https://noto-website-2.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip\n!unzip -p NotoSansCJKjp-hinted.zip NotoSansCJKjp-Regular.otf > NotoSansCJKjp-Regular.otf\n!rm NotoSansCJKjp-hinted.zip\n\nfont = ImageFont.truetype('./NotoSansCJKjp-Regular.otf', fontsize, encoding='utf-8')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"df_train.head()\n\"\"\"\nImage_id\n一般的なID列\n\nlabels\n[ユニコード、　x, y, weight, high]\nxとyは始点\nweightとhighは枠の大きさを表している\nつまり文字を抽出したかったら\n[x, y, x+weight, y+high]\nの長方形を抜き取れば良い\n\"\"\"\n\n\"\"\"\n提出するもの\ncsv形式\nid列とlabels列\nid列は画像のIDを入れればOK\n\nlabels列\n[ユニコード、ｘ座標、ｙ座標]\nここの座標は真ん中で良いそう\n\"\"\"\n\n\"\"\"\nとなると、\n\n前処理\n1.文字と座標を抜き取って単純な画像分類モデルのトレーニングデータのようなものを作成する\n\nモデル作成\n2.１で作成したデータを学習させる\n3.OCRみたいなもので画像から文字を検出するモデルも作成（古代のかなだから学習済みモデルがあるかはわからない）\n\n予測\n4.テストデータから文字を取り出す\n5.2で作った画像分類モデルに4の画像データを学習させる\n\nsubmit\n6.データの整形＆submit\n\nという流れができるのかな（間違っていたら教えてください）\n\nとはいえ4781もラベルがあるデータとなると多少の工夫は必要そう\nそれに実行時間も相当長くなりそうだ......\n32x32の画像を１０万枚学習させたとして、どれくらいの時間がかかるのだろうか（やってみなくちゃわからない）\n\"\"\"","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"len(unicode_map)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# This function takes in a filename of an image, and the labels in the string format given in train.csv, and returns an image containing the bounding boxes and characters annotated\n\n\"\"\"\nアレンジしました\n\"\"\"\ndef visualize_training_data(image_fn, labels):\n    # Convert annotation string to array\n\n    labels = np.array(str(labels).split(' ')).reshape(-1, 5)\n    # print(\"labelsです\", labels)\n    # print(\"label.shape です\", labels.shape, len(labels))\n    # Read image\n    imsource = Image.open(image_fn).convert('RGBA')\n\n    memo2 = np.array(labels)[:, 0]  # ラベルが入る\n    memo3 = np.zeros((len(labels), 32, 32, 4)).astype(\"int32\")  # Imageデータが入る\n    # print(memo3.shape)\n    \"\"\"\n    weight, highを見ていると64くらいでちょうどいい？感じがするので64にしました。\n    \"\"\"\n    # print(memo3)\n    # print(labels.shape)\n\n    for i, (codepoint, x, y, w, h) in enumerate(labels):\n        # print(i)\n        x, y, w, h = int(x), int(y), int(w), int(h)\n        \"\"\"\n        ここから画像の切り抜きを行う\n        \"\"\"\n        # print(np.asarray(img_crop).shape)\n        \n        # 画像から文字の部分を抜き取る\n        img_crop = imsource.crop((x, y, x+w, y+h))\n        \n        img_crop = np.asarray(img_crop.resize((32, 32)))\n        \n        # print(np.array(img_crop).shape)\n        \"\"\"\n        print(np.array(img_crop).shape)\n        \n        # (64, 64, 4)\n        \"\"\"\n        # arrayに入れる\n        memo3[i, :, :, :] = np.asarray(img_crop).astype(\"int32\")\n    \n    # ラベルと取り出した文字のデータもreturn\n    return memo2, memo3","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":false,"trusted":true},"cell_type":"code","source":"from glob import glob\nfrom tqdm import tqdm\nimport gc\nimport matplotlib.font_manager as fm\n\nprop = fm.FontProperties(fname=\"./NotoSansCJKjp-Regular.otf\")\n\"\"\"\n適当にコメント付けます\n\"\"\"\ntotal = 800\ni = 0\nfor x in glob(\"../input/train_images/*.jpg\"):\n    # print(x)\n    # print(df_train.head())\n    # path = x.split(\"/\")[3]\n    # local\n    path = x.split(\"/\")[3]\n    path = path.split(\".\")[0]\n\n    memo1 = df_train.values[df_train[\"image_id\"] == path].flatten()\n    # print(memo1)\n    # print(memo1[1])\n\n    try:\n        \"\"\"\n        1ページ全てイラストだった場合は飛ばす。（nanになるためValueError)\n        \"\"\"\n        labels = memo1[1]\n        # print(labels)\n        \n        memo2, memo3 = visualize_training_data(x, labels)\n\n        # print(memo3.shape)\n        \n        # save\n        # np.save(\"npyy/\" + str(i) + \"image.npy\", memo3)\n        # np.save(\"npyy/\" + str(i) + \"labels.npy\", memo2)\n\n        if i == 0:\n            image_data = memo3.copy()\n            labels_data = memo2.copy()\n        elif i % 400 == 0:\n            \"\"\"\n            400枚ごとに1つのファイルを作成します。\n            \"\"\"\n            np.save(\"image_data_\" + str(i) + \".npy\", image_data)\n            np.save(\"labels_data_\" + str(i) + \".npy\", labels_data)\n            del image_data, labels_data\n            gc.collect()\n            image_data = memo3.copy()\n            labels_data = memo2.copy()\n        else:\n            image_data = np.append(image_data, memo3, axis=0)\n            labels_data = np.append(labels_data, memo2, axis=0)\n        # イラストページでカウントしないように\n        i += 1\n        # i.update(10)\n    except ValueError:\n        print(\"イラストページです！！\")\n    \n    if i % 50 == 0:\n        \"\"\"\n        取り出した画像を表示します\n        \"\"\"\n        plt.rcParams[\"font.size\"] = 15\n\n        char = memo2[10]\n        plt.title(unicode_map[char], fontproperties=prop, fontsize=50)\n        plt.imshow(memo3[10, :, :, :])\n        plt.show()\n        \n    if i == total:\n        np.save(\"image_data_\" + str(i) +\".npy\", image_data)\n        np.save(\"labels_data_\" + str(i) + \".npy\", labels_data)\n        break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\nカーネルのDiskの制限で3800枚全ての画像の保存は出来ませんでした。（メモリエラーかもしれない?）\n\n解決策も何かあればコメントください。\n\n僕はあとでローカル環境で実行してみようと思っています。\n\"\"\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}