{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Purpose\nThis image cropping function is developped for the competition \"Bengali.AI Handwritten Grapheme Classification\". Original Image data has some problems to be solved:\n* image is not located in the center\n* some of images have noise, which disturbs Machine Learning"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport os\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom skimage.transform import resize\nimport time\nimport gc\nfrom sklearn.metrics import confusion_matrix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IM_SIZE = 64\nn_file = 4\nn_each_train = 50210","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 1. Functions\nCropping function and image plot function are defined. Cropping function has two features: cropping and centering."},{"metadata":{"trusted":true},"cell_type":"code","source":"#croping image\ndef crop_image(array, image_size, noise):\n    threshold = 10\n    threshold2 = 150\n    # to avoid noise on the boundary\n    if np.mean(array, axis = 1)[0] > noise + 10:\n        array = array[2:,:]\n    if np.mean(array, axis = 1)[-1] > noise + 10:\n        array = array[0:-3,:]\n    if np.mean(array, axis = 0)[0] > noise + 10:\n        array = array[:,2:]\n    if np.mean(array, axis = 0)[-1] > noise + 10:\n        array = array[:,0:-3]\n    \n    x_max = np.quantile(array, axis = 1, q = 0.95)\n    x_max2 = np.where(x_max >= threshold)[0]     \n    \n    T = 0.02\n    while x_max2.shape[0] < 2:\n        x_max = np.quantile(array, axis = 1, q = 0.95 + T)\n        x_max2 = np.where(x_max >= threshold)[0] \n        T += 0.02\n        T = min(T, 0.05)\n    \n    y_max = np.quantile(array, axis = 0, q = 0.95)    \n    y_max2 = np.where(y_max >= threshold)[0] \n    \n    T = 0.02\n    while y_max2.shape[0] < 2:\n        y_max = np.quantile(array, axis = 0, q = 0.95 + T)    \n        y_max2 = np.where(y_max >= threshold)[0] \n        T += 0.02\n        T = min(T, 0.05)\n    \n    x_max_m = np.max(array, axis = 1)\n    y_max_m = np.max(array, axis = 0)    \n    x_max2_m = np.where(x_max_m >= threshold2)[0]   \n    y_max2_m = np.where(y_max_m >= threshold2)[0]         \n    \n    T = 10\n    while x_max2_m.shape[0] < 2:\n        x_max2_m = np.where(x_max_m >= threshold2 - T)[0] \n        T += 25\n    T = 10\n    while y_max2_m.shape[0] < 2:\n        y_max2_m = np.where(y_max_m >= threshold2 - T)[0] \n        T += 25    \n    \n    x1 = int(np.mean(np.array([x_max2[0], x_max2_m[0]])))\n    x2 = int(np.mean(np.array([x_max2[-1], x_max2_m[-1]]))) \n    \n    y1 = int(np.mean(np.array([y_max2[0], y_max2_m[0]])))\n    y2 = int(np.mean(np.array([y_max2[-1], y_max2_m[-1]])))\n    \n    margin = 3\n    LX = x2-x1\n    LY = y2-y1    \n    DL = LX - LY\n    ML = np.max([x2-x1, y2-y1])\n    array2 = np.zeros((ML + 2*margin, ML + 2*margin))\n    \n    # centering\n    if DL > 0:\n        array2[margin:-margin,int(abs(DL)/2)+margin:int(abs(DL)/2)+LY+margin] = array[x1:x2,y1:y2]\n    \n    else:\n        array2[int(abs(DL)/2)+margin:int(abs(DL)/2)+LX+margin,margin:-margin] = array[x1:x2,y1:y2]\n\n    return resize(array2, (image_size, image_size), preserve_range=True).astype(\"uint8\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def image_plot(array1, array2):\n    n = array1.shape[0]\n    m = int(n/10)\n    fig, ax = plt.subplots(10, 10, figsize = (19, 20))\n    cmap = \"gray\"\n    \n    for i in range(n):\n        x = int(i/10)\n        y = i % 10\n        ax[2*x, y].imshow(array1[i,:,:], cmap)\n        ax[2*x, y].set_xticks([], [])\n        ax[2*x, y].set_yticks([], [])\n        ax[2*x+1, y].imshow(array2[i,:,:], cmap)\n        ax[2*x+1, y].set_xticks([], [])\n        ax[2*x+1, y].set_yticks([], [])\n    \n    plt.show()\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 2. Read Train files"},{"metadata":{"trusted":true},"cell_type":"code","source":"list_col = []\nfor i in range(32332):\n    list_col.append(str(i))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"time1 = time.time()\ntrain_m = np.zeros((8000, IM_SIZE, IM_SIZE), dtype = \"uint8\")\ntrain_before = np.zeros((8000, 137, 236), dtype = \"uint8\")\ntrain_m0 = np.zeros((137, 236), dtype = \"int16\")\nk = 0\nfor i in range(n_file):\n    time3 = time.time()\n    print(\"reading train file\",i)\n    directory = \"/kaggle/input/bengaliai-cv19/train_image_data_\"+str(i)+\".parquet\"\n    train_df0 = pd.read_parquet(directory, engine = \"pyarrow\", columns = list_col)\n\n    gc.collect()\n\n    print(\"image cropping start\",i)\n    time3 = time.time()\n    samples = np.random.randint(0,n_each_train,2000)\n    for j in samples:\n        train_m0[:,:] = np.reshape(np.array(train_df0.iloc[j,:], dtype = \"int16\"), (137, 236))\n        train_m0[:,:] = - train_m0[:,:] + 255\n        add = 255 - np.max(train_m0)\n        train_m0[:,:] = train_m0[:,:] + add\n        noise = 65 + add\n        train_m0[train_m0 < noise] = 0 # Noise Reduction\n        train_m[k,:,:] = crop_image(train_m0, image_size = IM_SIZE, noise = noise).astype(\"uint8\")\n        train_before[k,:,:] = train_m0\n        k += 1   \n\n    del train_df0\n    gc.collect()\n\ntime2 = time.time()\nprint(int(time2-time1), \"sec\")\n\ndel train_m0\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3. Cropped Images\nHere, both original and cropped images are plotted. Total number is 500 respectively."},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples = np.random.randint(0,8000, size = 50)\nimage_plot(train_before[samples,:,:], train_m[samples,:,:])","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}