{"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_minor":4,"nbformat":4,"cells":[{"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\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 read-only \"../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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-02T11:42:35.770345Z","iopub.execute_input":"2022-11-02T11:42:35.770987Z","iopub.status.idle":"2022-11-02T11:43:07.276403Z","shell.execute_reply.started":"2022-11-02T11:42:35.770896Z","shell.execute_reply":"2022-11-02T11:43:07.275691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install keras-tuner","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:07.279582Z","iopub.execute_input":"2022-11-02T11:43:07.279785Z","iopub.status.idle":"2022-11-02T11:43:16.117133Z","shell.execute_reply.started":"2022-11-02T11:43:07.279759Z","shell.execute_reply":"2022-11-02T11:43:16.116220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nimport numpy as np\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:16.118908Z","iopub.execute_input":"2022-11-02T11:43:16.119165Z","iopub.status.idle":"2022-11-02T11:43:20.587331Z","shell.execute_reply.started":"2022-11-02T11:43:16.119130Z","shell.execute_reply":"2022-11-02T11:43:20.586549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/ultra-mnist/train.csv')\nsubmission = pd.read_csv(\"/kaggle/input/ultra-mnist/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:20.589593Z","iopub.execute_input":"2022-11-02T11:43:20.589849Z","iopub.status.idle":"2022-11-02T11:43:20.650905Z","shell.execute_reply.started":"2022-11-02T11:43:20.589814Z","shell.execute_reply":"2022-11-02T11:43:20.650202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:20.652120Z","iopub.execute_input":"2022-11-02T11:43:20.652352Z","iopub.status.idle":"2022-11-02T11:43:20.671629Z","shell.execute_reply.started":"2022-11-02T11:43:20.652320Z","shell.execute_reply":"2022-11-02T11:43:20.670968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random_sample = train.sample() #give one sample\n\n#convert sample into list\nname_image = random_sample.to_numpy()[0][0]\nname_image ","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:20.672947Z","iopub.execute_input":"2022-11-02T11:43:20.673177Z","iopub.status.idle":"2022-11-02T11:43:20.681479Z","shell.execute_reply.started":"2022-11-02T11:43:20.673146Z","shell.execute_reply":"2022-11-02T11:43:20.680812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random_sample","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:20.682794Z","iopub.execute_input":"2022-11-02T11:43:20.683320Z","iopub.status.idle":"2022-11-02T11:43:20.693677Z","shell.execute_reply.started":"2022-11-02T11:43:20.683286Z","shell.execute_reply":"2022-11-02T11:43:20.692710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\n\nrandom_image = cv2.imread(f'../input/ultra-mnist/train/{name_image}.jpeg', 0)\nplt.imshow(random_image, cmap='Greys_r');","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:20.695264Z","iopub.execute_input":"2022-11-02T11:43:20.695571Z","iopub.status.idle":"2022-11-02T11:43:22.629429Z","shell.execute_reply.started":"2022-11-02T11:43:20.695507Z","shell.execute_reply":"2022-11-02T11:43:22.628756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Background Preprocessing\n---\nWe can use this function for each image. It is different from fuction that was used for creation Ultra-MNIST-Black dataset. But my function is some better (in my opinion), because sometimes there were mistakes in that dataset. In this function I look at left and top edges each square and compare them with neighbor squares.","metadata":{}},{"cell_type":"code","source":"def background_converter(img):\n    #convert img into numpy array\n    img = np.array(img, dtype='int32')\n    \n    for i in range(4):\n        for j in range(4):\n            top, left = False, False\n            img_slice = img[i * 1000:(i + 1) * 1000, j * 1000:(j + 1) * 1000]\n            \n            top_slice = img[i * 1000, j * 1000:(j + 1) * 1000]\n            left_slice = img[i * 1000:(i + 1) * 1000, j * 1000]\n            if i > 0:\n                top_slice_oppos = img[i * 1000 - 1, j * 1000:(j + 1) * 1000]\n            if j > 0:\n                left_slice_oppos = img[i * 1000:(i + 1) * 1000, j * 1000 - 1]\n            \n            if (i == 0 and top_slice.mean() > 250\n                or i > 0 and (top_slice != top_slice_oppos).sum() > 900):\n                top = True\n                print(i)\n                \n            if (j == 0 and left_slice.mean() > 250\n                or j > 0 and (left_slice != left_slice_oppos).sum() > 900):\n                left = True\n                print(j)\n                \n            if top or left:\n                img[i * 1000:(i + 1) * 1000, j * 1000:(j + 1) * 1000] = np.abs(img_slice - 255) \n                print(i,j)\n    return img.astype('uint8')","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:22.630763Z","iopub.execute_input":"2022-11-02T11:43:22.631198Z","iopub.status.idle":"2022-11-02T11:43:22.641393Z","shell.execute_reply.started":"2022-11-02T11:43:22.631159Z","shell.execute_reply":"2022-11-02T11:43:22.640540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(18, 10))\nax[0].imshow(random_image, cmap='Greys_r')\nrandom_image_processed = background_converter(random_image)\nax[1].imshow(random_image_processed, cmap='Greys_r')","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:22.644230Z","iopub.execute_input":"2022-11-02T11:43:22.644542Z","iopub.status.idle":"2022-11-02T11:43:27.207334Z","shell.execute_reply.started":"2022-11-02T11:43:22.644500Z","shell.execute_reply":"2022-11-02T11:43:27.206663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We use threshold if the image value >200 convert it into 255 otherwise same.","metadata":{}},{"cell_type":"code","source":"def threshold_image(img):\n    return cv2.threshold(img, 200, 255, cv2.THRESH_BINARY)[1]\n","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:27.208564Z","iopub.execute_input":"2022-11-02T11:43:27.208928Z","iopub.status.idle":"2022-11-02T11:43:27.213427Z","shell.execute_reply.started":"2022-11-02T11:43:27.208893Z","shell.execute_reply":"2022-11-02T11:43:27.212764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"threshold_img = threshold_image(random_image_processed)\nplt.imshow(threshold_img, cmap='Greys_r');","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:27.214829Z","iopub.execute_input":"2022-11-02T11:43:27.215315Z","iopub.status.idle":"2022-11-02T11:43:28.751970Z","shell.execute_reply.started":"2022-11-02T11:43:27.215280Z","shell.execute_reply":"2022-11-02T11:43:28.751222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bound_rects(img):\n    contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    bound_rects = []\n\n    for i, c in enumerate(contours):\n            rect = cv2.boundingRect(c)\n            if rect[3] < 9 or rect[2] < 2 or not 0.5 < rect[3] / rect[2] <= 10:\n                continue\n            bound_rects.append(rect)\n    \n    return np.array(bound_rects)","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.753386Z","iopub.execute_input":"2022-11-02T11:43:28.753632Z","iopub.status.idle":"2022-11-02T11:43:28.759697Z","shell.execute_reply.started":"2022-11-02T11:43:28.753597Z","shell.execute_reply":"2022-11-02T11:43:28.758610Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bounding_boxes = get_bound_rects(threshold_img)\nbounding_boxes","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.761258Z","iopub.execute_input":"2022-11-02T11:43:28.761523Z","iopub.status.idle":"2022-11-02T11:43:28.785700Z","shell.execute_reply.started":"2022-11-02T11:43:28.761490Z","shell.execute_reply":"2022-11-02T11:43:28.785060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def is_point_in_rect(point, rect, k):\n    x0, y0 = point\n    d = k * max(rect[2], rect[3])\n    centerx = rect[0] + rect[2] // 2\n    centery = rect[1] + rect[3] // 2\n    x1, y1, x2, y2 = centerx - d, centery - d, centerx + d, centery + d\n    if x1 <= x0 <= x2 and y1 <= y0 <= y2:\n        return True\n    return False","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.786880Z","iopub.execute_input":"2022-11-02T11:43:28.787125Z","iopub.status.idle":"2022-11-02T11:43:28.794241Z","shell.execute_reply.started":"2022-11-02T11:43:28.787093Z","shell.execute_reply":"2022-11-02T11:43:28.793457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_intersection(rect1, rect2, k):\n    for i in 0, rect1[2]:\n        for j in 0, rect1[3]:\n            point = rect1[0] + i, rect1[1] + j\n            if is_point_in_rect(point, rect2, k):\n                return True\n    for i in 0, rect2[2]:\n        for j in 0, rect2[3]:\n            point = rect2[0] + i, rect2[1] + j\n            if is_point_in_rect(point, rect1, k):\n                return True\n    return False","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.795315Z","iopub.execute_input":"2022-11-02T11:43:28.795595Z","iopub.status.idle":"2022-11-02T11:43:28.804961Z","shell.execute_reply.started":"2022-11-02T11:43:28.795559Z","shell.execute_reply":"2022-11-02T11:43:28.804279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def remove_intersec_rects(bound_rects, k):\n    intersec = np.ones(bound_rects.shape[0]).astype(bool)\n    for i, rect1 in enumerate(bound_rects):\n        for j, rect2 in enumerate(bound_rects):\n            if i == j:\n                continue\n            if check_intersection(rect1, rect2, k):\n                s1 = rect1[2] * rect1[3]\n                s2 = rect2[2] * rect2[3]\n                if s1 >= s2:\n                    intersec[j] = False\n                else:\n                    intersec[i] = False\n    return bound_rects[intersec]","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.805986Z","iopub.execute_input":"2022-11-02T11:43:28.806230Z","iopub.status.idle":"2022-11-02T11:43:28.816494Z","shell.execute_reply.started":"2022-11-02T11:43:28.806191Z","shell.execute_reply":"2022-11-02T11:43:28.815725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bounding_boxes = remove_intersec_rects(bounding_boxes, 0.6)\nbounding_boxes","metadata":{"execution":{"iopub.status.busy":"2022-11-02T11:43:28.817518Z","iopub.execute_input":"2022-11-02T11:43:28.818073Z","iopub.status.idle":"2022-11-02T11:43:28.831436Z","shell.execute_reply.started":"2022-11-02T11:43:28.818039Z","shell.execute_reply":"2022-11-02T11:43:28.830626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}