{"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":"markdown","source":"**This notebook contains only a function which help you to remove background from images in the dataset.**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nfrom matplotlib import pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-13T19:59:57.679547Z","iopub.execute_input":"2022-03-13T19:59:57.680168Z","iopub.status.idle":"2022-03-13T19:59:58.080150Z","shell.execute_reply.started":"2022-03-13T19:59:57.680048Z","shell.execute_reply":"2022-03-13T19:59:58.079172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('../input/ultra-mnist/train.csv')\n\nrandom_sample = train_df.sample()\nrandom_image = cv2.imread(f'../input/ultra-mnist/train/{random_sample.to_numpy()[0][0]}.jpeg', 0)","metadata":{"execution":{"iopub.status.busy":"2022-03-13T20:31:49.354594Z","iopub.execute_input":"2022-03-13T20:31:49.354874Z","iopub.status.idle":"2022-03-13T20:31:49.429894Z","shell.execute_reply.started":"2022-03-13T20:31:49.354844Z","shell.execute_reply":"2022-03-13T20:31:49.428963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"My function 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. ","metadata":{}},{"cell_type":"markdown","source":"In this function I look at left and top edges each square and compare them with neighbor squares. Almost always if we should to change a color of square, these edges will be opposite.","metadata":{}},{"cell_type":"code","source":"def background_converter(img):\n    # at first convert our array to int32 from uint8 (numeric format OpenCV)\n    img = np.array(img, dtype='int32')\n    \n    # then we go through 16 squares 1000x1000\n    for i in range(4):\n        for j in range(4):\n            \n            # top and left are indicators that help us understand whether we need to change color of square or not\n            top, left = False, False\n            \n            # slice of square\n            img_slice = img[i * 1000:(i + 1) * 1000, j * 1000:(j + 1) * 1000]\n            \n            # slices of our square's edges\n            top_slice = img[i * 1000, j * 1000:(j + 1) * 1000]\n            left_slice = img[i * 1000:(i + 1) * 1000, j * 1000]\n            \n            # slices of neigbour squares' edges\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            # check top edge\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                \n            # check left edge\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                \n            # make final decision    \n            if top or left:\n                img[i * 1000:(i + 1) * 1000, j * 1000:(j + 1) * 1000] = np.abs(img_slice - 255) \n                \n    # convert array to uint8 back and return from function\n    return img.astype('uint8')","metadata":{"execution":{"iopub.status.busy":"2022-03-13T20:08:43.734051Z","iopub.execute_input":"2022-03-13T20:08:43.734323Z","iopub.status.idle":"2022-03-13T20:08:43.746526Z","shell.execute_reply.started":"2022-03-13T20:08:43.734294Z","shell.execute_reply":"2022-03-13T20:08:43.745416Z"},"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-03-13T20:08:56.813221Z","iopub.execute_input":"2022-03-13T20:08:56.813478Z","iopub.status.idle":"2022-03-13T20:09:02.277027Z","shell.execute_reply.started":"2022-03-13T20:08:56.813450Z","shell.execute_reply":"2022-03-13T20:09:02.276043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(10, 10, figsize=(18, 20))\n\nfor i in range(100):\n    axis = ax[i // 10][i % 10]\n    \n    random_sample = train_df.sample()\n    random_image = cv2.imread(f'../input/ultra-mnist/train/{random_sample.to_numpy()[0][0]}.jpeg', 0)\n    random_image_processed = background_converter(random_image)\n    axis.imshow(random_image_processed, cmap='Greys_r')\n    axis.set_xticklabels([])\n    axis.set_yticklabels([])","metadata":{"execution":{"iopub.status.busy":"2022-03-13T20:26:26.743225Z","iopub.execute_input":"2022-03-13T20:26:26.743757Z","iopub.status.idle":"2022-03-13T20:27:42.546755Z","shell.execute_reply.started":"2022-03-13T20:26:26.743708Z","shell.execute_reply":"2022-03-13T20:27:42.545936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the near future I will try to make dataset with this method.","metadata":{}},{"cell_type":"markdown","source":"If you find any mistakes in my method or any improvements I will be glad to hear it. Thanks!","metadata":{}}]}