{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nimport cv2\nfrom IPython.display import Image\n\nfrom PIL import Image, ImageDraw, ImageFont\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom tqdm import tqdm_notebook as tqdm\nfrom skimage import io, transform\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir('../input')","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"test_boxes = pd.read_csv('../input/frcnnoutput/torchvision_frcnn_3.csv')\n\nunicode_map = {codepoint: char for codepoint, char in pd.read_csv('../input/kuzushiji-recognition/unicode_translation.csv').values}\nunicode_vocab = sorted(list(unicode_map))\nunicode2id = {codepoint: i for (i, codepoint) in enumerate(unicode_vocab)}\n\nprint(test_boxes.shape)\ntest_boxes.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_boxes['boxes'] = test_boxes['labels']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_specific(img_id, x, y):\n    fill_cent=[1, 0, 0]\n    img = load_image('../input/kuzushiji-recognition/test_images/{}.jpg'.format(img_id))\n    radius = 10\n    img[x - radius: x + radius, y - radius: y + radius] = fill_cent\n    fig, axs = plt.subplots(1, 1, figsize=(60, 60))\n    plt.imshow(img, interpolation='bilinear')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Malisiewicz et al.\ndef non_max_suppression_fast(boxes, overlapThresh=0.5):\n    # if there are no boxes, return an empty list\n    if len(boxes) == 0:\n        return []\n \n    # if the bounding boxes integers, convert them to floats --\n    # this is important since we'll be doing a bunch of divisions\n    if boxes.dtype.kind == \"i\":\n        boxes = boxes.astype(\"float\")\n \n    # initialize the list of picked indexes\t\n    pick = []\n \n    # grab the coordinates of the bounding boxes\n    x1 = boxes[:,0]\n    y1 = boxes[:,1]\n    x2 = boxes[:,2]\n    y2 = boxes[:,3]\n \n    # compute the area of the bounding boxes and sort the bounding\n    # boxes by the bottom-right y-coordinate of the bounding box\n    area = (x2 - x1 + 1) * (y2 - y1 + 1)\n    idxs = np.argsort(y2)\n \n    # keep looping while some indexes still remain in the indexes\n    # list\n    while len(idxs) > 0:\n        # grab the last index in the indexes list and add the\n        # index value to the list of picked indexes\n        last = len(idxs) - 1\n        i = idxs[last]\n        pick.append(i)\n \n        # find the largest (x, y) coordinates for the start of\n        # the bounding box and the smallest (x, y) coordinates\n        # for the end of the bounding box\n        xx1 = np.maximum(x1[i], x1[idxs[:last]])\n        yy1 = np.maximum(y1[i], y1[idxs[:last]])\n        xx2 = np.minimum(x2[i], x2[idxs[:last]])\n        yy2 = np.minimum(y2[i], y2[idxs[:last]])\n \n        # compute the width and height of the bounding box\n        w = np.maximum(0, xx2 - xx1 + 1)\n        h = np.maximum(0, yy2 - yy1 + 1)\n\n        # compute the ratio of overlap\n        overlap = (w * h) / area[idxs[:last]]\n\n        # delete all indexes from the index list that have\n        idxs = np.delete(idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0])))\n\n    # return only the bounding boxes that were picked using the\n    # integer data type\n    return boxes[pick].astype(\"int\"), pick","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def cropImage(boxes, loop1_index):\n    if isinstance(boxes, float):\n        return None\n\n    filepath = '../input/kuzushiji-recognition/test_images/{}.jpg'.format(row.image_id)\n    \n    img = cv2.imread(filepath)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    boxes = boxes.split(\" \")\n\n    # to get the highest speed, we use numpy for the cropping of the images\n    # numpy doesn't support strings in their ndarrays\n    # that's why we move unicodes outside of labels\n    unicode = boxes[::5]\n    del boxes[::5]\n    \n\n    boxes = np.array(boxes, dtype=np.int16)\n\n    boxes = boxes.reshape(-1, 4)\n\n    boxes[:, 2] = np.sum(a=boxes[:,[0,2]], axis=1)\n    boxes[:, 3] = np.sum(a=boxes[:,[1,3]], axis=1)\n\n    print(boxes)\n    \n    return [img[label[1]:label[3], label[0]:label[2]] for loop2_index, label in enumerate(boxes)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for loop1_index, (list_index, row) in tqdm(enumerate(test_boxes[:1].iterrows())):\n    temp = cropImage(row.boxes, loop1_index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"rows = 9\ncolumns = 9\nfig = plt.figure(figsize=(40, 20))\n\nfor i in range(1, rows*columns + 1):\n    fig.add_subplot(rows, columns, i)\n    plt.imshow(temp[i], aspect='equal')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_and_save(boxes, loop1_index):\n    error_counter = 0\n    if isinstance(boxes, float):\n        return None\n\n    filepath = '../input/kuzushiji-recognition/test_images/{}.jpg'.format(row.image_id)\n    \n    img = cv2.imread(filepath)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    boxes = boxes.split(\" \")\n\n    unicode = boxes[::5]\n    del boxes[::5]\n\n    boxes = np.array(boxes, dtype=np.int16)\n    boxes = boxes.reshape(-1, 4)\n    centers_x = boxes[:, 0] + boxes[:, 2] * 0.5\n    centers_y = boxes[:, 1] + boxes[:, 3] * 0.5\n    \n    boxes[:, 2] = np.sum(a=boxes[:,[0,2]], axis=1)\n    boxes[:, 3] = np.sum(a=boxes[:,[1,3]], axis=1)\n    \n    #boxes, pick = non_max_suppression_fast(boxes, 0.5)\n    #centers = centers[pick] \n    \n    if not os.path.exists('../cropped'):\n        os.mkdir('../cropped')\n    if not os.path.exists('../cropped/{}'.format(row.image_id)):\n        os.mkdir('../cropped/{}'.format(row.image_id))\n    \n    for loop2_index, label in enumerate(boxes):\n        try:\n            Image.fromarray(img[label[1]:label[3], label[0]:label[2]]).save('../cropped/{}/{}_{}.jpg'.format(row.image_id, centers_x[loop2_index], centers_y[loop2_index]))\n        except Exception as e:\n            error_counter += 1\n    return error_counter","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from multiprocessing import Process, current_process\n\nprocesses = []\n\npbar = tqdm(total=len(test_boxes))\nfor loop1_index, (list_index, row) in enumerate(test_boxes.iterrows()):\n    process = Process(target=crop_and_save, args=(row.boxes, loop1_index))\n    pbar.update(1)\n    processes.append(process)\n    \n    process.start()\npbar.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import shutil\nshutil.make_archive(\"cropped\", \"zip\", '../cropped')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}