{"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":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\n\nimport cv2\nimport gc\n\nfrom tqdm import tqdm, trange\nfrom glob import glob\nimport skimage.io as io\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-06T11:59:22.339576Z","iopub.execute_input":"2022-09-06T11:59:22.339985Z","iopub.status.idle":"2022-09-06T11:59:22.34768Z","shell.execute_reply.started":"2022-09-06T11:59:22.339952Z","shell.execute_reply":"2022-09-06T11:59:22.345544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/mayo-clinic-strip-ai/train.csv')\ndf.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-06T11:58:45.6736Z","iopub.execute_input":"2022-09-06T11:58:45.67409Z","iopub.status.idle":"2022-09-06T11:58:45.70238Z","shell.execute_reply.started":"2022-09-06T11:58:45.674058Z","shell.execute_reply":"2022-09-06T11:58:45.701452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# If want to see the code working for random examples.\n# k = np.random.randint(0, df.shape[0])\n\nk = 463\npath = f'../input/mayo-clinic-strip-ai/train/{df.iloc[k][0]}.tif'\n\nplt.figure(figsize=(10,10))\nplt.imshow(cv2.resize(io.imread(path), (512,512)))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-06T11:58:45.704291Z","iopub.execute_input":"2022-09-06T11:58:45.70465Z","iopub.status.idle":"2022-09-06T11:58:56.400654Z","shell.execute_reply.started":"2022-09-06T11:58:45.704618Z","shell.execute_reply":"2022-09-06T11:58:56.399464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Here we can observe that there are lot of empty spaces in the above images this is the case with most of the image.","metadata":{}},{"cell_type":"markdown","source":"# Function to Crop the Vacant Space\n### Steps which will be followed to crop the space:\n* #### Identify the rows with very few unique pixel values.\n* #### Delete those rows from the numpy array.\n* #### Follow the same step with the columns.\n","metadata":{}},{"cell_type":"code","source":"def remove_spaces(img):\n    \n    print('Original image shape : ', img.shape)\n    print('Removing rows ..................')\n\n    \n#     Code to identify empty rows.\n    idx = []\n    for i in trange(img.shape[0]):\n        \n        if len(np.unique(img[i,:])) <= 100:\n            idx.append(i)\n            \n    print('Rows removed : ', len(idx))\n    \n    img = np.delete(img, idx, axis=0)\n    \n    print('New image shape : ', img.shape)\n    \n    print('Removing columns ..................')\n    idxy = []\n    for i in trange(img.shape[1]):\n        \n        if len(np.unique(img[:,i])) <= 100:\n            idxy.append(i)\n            \n    print('Columns removed : ', len(idxy))\n            \n    img = np.delete(img, idxy, axis=1)\n    print('New image shape : ', img.shape)\n    \n            \n    del idx, idxy\n    gc.collect()\n    \n    return img","metadata":{"execution":{"iopub.status.busy":"2022-09-06T11:59:01.603326Z","iopub.execute_input":"2022-09-06T11:59:01.604308Z","iopub.status.idle":"2022-09-06T11:59:01.617754Z","shell.execute_reply.started":"2022-09-06T11:59:01.604255Z","shell.execute_reply":"2022-09-06T11:59:01.616491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = io.imread(path)\nimg = remove_spaces(img)","metadata":{"execution":{"iopub.status.busy":"2022-09-06T11:59:41.578217Z","iopub.execute_input":"2022-09-06T11:59:41.578609Z","iopub.status.idle":"2022-09-06T12:00:31.903004Z","shell.execute_reply.started":"2022-09-06T11:59:41.578579Z","shell.execute_reply":"2022-09-06T12:00:31.901734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20, 20))\nplt.imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-06T12:00:31.90546Z","iopub.execute_input":"2022-09-06T12:00:31.905935Z","iopub.status.idle":"2022-09-06T12:00:50.057989Z","shell.execute_reply.started":"2022-09-06T12:00:31.90589Z","shell.execute_reply":"2022-09-06T12:00:50.057068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Here we can see the quality of the images which is very fine grained. If the pixels have not been altered by reshaping.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(20, 20))\nplt.imshow(cv2.resize(img, (512, 512)))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-06T12:00:50.059118Z","iopub.execute_input":"2022-09-06T12:00:50.059882Z","iopub.status.idle":"2022-09-06T12:00:53.448662Z","shell.execute_reply.started":"2022-09-06T12:00:50.059848Z","shell.execute_reply":"2022-09-06T12:00:53.447227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### This image is resized version of the above and not as fine grained as the previous one which has not been resized. So, resizing is indeed addition of noise and irregularity to the image.","metadata":{}},{"cell_type":"markdown","source":"# Using Maxpooling\n#### If we are ready to sacrifice some granularity of the image then. We can reduce the computation time drastically and size of the image by desired factor.","metadata":{}},{"cell_type":"code","source":"pool = tf.keras.layers.MaxPooling2D(2, 2)","metadata":{"execution":{"iopub.status.busy":"2022-09-06T12:00:53.45066Z","iopub.execute_input":"2022-09-06T12:00:53.451046Z","iopub.status.idle":"2022-09-06T12:00:54.677012Z","shell.execute_reply.started":"2022-09-06T12:00:53.451013Z","shell.execute_reply":"2022-09-06T12:00:54.675788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = io.imread(path)\n\nx = pool(tf.expand_dims(img, axis=0))\nimg = pool(x).numpy()\n\nimg = remove_spaces(img[0])","metadata":{"execution":{"iopub.status.busy":"2022-09-06T12:00:54.680788Z","iopub.execute_input":"2022-09-06T12:00:54.681687Z","iopub.status.idle":"2022-09-06T12:01:21.380063Z","shell.execute_reply.started":"2022-09-06T12:00:54.681652Z","shell.execute_reply":"2022-09-06T12:01:21.378913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20, 20))\nplt.imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-06T12:01:50.106194Z","iopub.execute_input":"2022-09-06T12:01:50.106617Z","iopub.status.idle":"2022-09-06T12:01:51.86377Z","shell.execute_reply.started":"2022-09-06T12:01:50.106583Z","shell.execute_reply":"2022-09-06T12:01:51.861829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"###  Here this image is not so, fine grained as compared to the image cropped without using the max - pooling. But this reduces the images size drastically without changing the original pixels although we lost some information in this process. But this is not bad as the resized one.","metadata":{}},{"cell_type":"code","source":"# def remove_spaces(img):\n    \n#     print('Original image shape : ', img.shape)\n#     print('Removing rows ..................')\n\n    \n# #     Code to identify empty rows.\n#     idx = []\n#     for i in trange(img.shape[0]):\n        \n#         k1 = len(np.unique(img[:,:,0][i,:]))\n#         if k1 > 128:\n#             continue\n        \n#         k1 = k1 + len(np.unique(img[:,:,1][i,:]))\n#         if k1 > 128:\n#             continue\n        \n#         k1 = k1 + len(np.unique(img[:,:,2][i,:]))\n#         if k1 > 128:\n#             continue\n            \n#         idx.append(i)        \n        \n            \n#     print('Rows removed : ', len(idx))\n    \n#     img = np.delete(img, idx, axis=0)\n    \n#     print('New image shape : ', img.shape)\n    \n#     print('Removing columns ..................')\n#     idxy = []\n#     for i in trange(img.shape[1]):\n        \n#         k1 = len(np.unique(img[:,:,0][:,i]))\n#         if k1 > 128:\n#             continue\n        \n#         k1 = k1 + len(np.unique(img[:,:,1][:,i]))\n#         if k1 > 128:\n#             continue\n        \n#         k1 = k1 + len(np.unique(img[:,:,2][:,i]))\n#         if k1 > 128:\n#             continue\n        \n#         idxy.append(i)\n            \n#     print('Columns removed : ', len(idxy))\n            \n#     img = np.delete(img, idxy, axis=1)\n#     print('New image shape : ', img.shape)\n    \n            \n#     del idx, idxy\n#     gc.collect()\n    \n#     return img","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### In this code some heuristics has been used to speed up the removing spaces process.","metadata":{}},{"cell_type":"markdown","source":"# Conclusion\n* ### But even after using this method I am unable to process all the image data we have been provided with due to the out of memory limit exceeded.\n* ### But I find this method quite effective to remove the spaces so, that's why I am publishing this notebook. Do comment for suggestions and improvisations.","metadata":{}}]}