{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Google Landmark Recognition 2020"},{"metadata":{},"cell_type":"markdown","source":"### Import required libraries"},{"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 matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom tqdm import tqdm_notebook as tqdm\n\nimport glob\nimport cv2\nimport os\n\nfrom colorama import Fore, Back, Style\n\n# Setting color palette.\nplt.rcdefaults()\nplt.style.use('dark_background')\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Declare path variables"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# Assigning paths to variables\nINPUT_PATH = os.path.join('..', 'input')\nDATASET_PATH = os.path.join(INPUT_PATH, 'landmark-recognition-2020')\nTRAIN_IMAGE_PATH = os.path.join(DATASET_PATH, 'train')\nTEST_IMAGE_PATH = os.path.join(DATASET_PATH, 'test')\nTRAIN_CSV_PATH = os.path.join(DATASET_PATH, 'train.csv')\nSUBMISSION_CSV_PATH = os.path.join(DATASET_PATH, 'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Load CSV files"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv(TRAIN_CSV_PATH)\nprint(\"training dataset has {} rows and {} columns\".format(train.shape[0],train.shape[1]))\n\nsubmission = pd.read_csv(SUBMISSION_CSV_PATH)\nprint(\"submission dataset has {} rows and {} columns \\n\".format(submission.shape[0],submission.shape[1]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Folder Structure"},{"metadata":{"trusted":true},"cell_type":"code","source":"# understand folder structure\nprint(Fore.YELLOW + \"If you want to access image a40d00dc4fcc3a10, you should traverse as shown below:\\n\",Style.RESET_ALL)\n\nprint(Fore.GREEN + f\"Image name: {train['id'].iloc[9]}\\n\",Style.RESET_ALL)\n\nprint(Fore.BLUE + f\"First folder to look inside: {train['id'][9][0]}\")\nprint(Fore.BLUE + f\"Second folder to look inside: {train['id'][9][1]}\")\nprint(Fore.BLUE + f\"Second folder to look inside: {train['id'][9][2]}\",Style.RESET_ALL)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Build dictionary to store image paths & labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(Fore.BLUE + f\"{'---'*20} \\n Mapping for Training Data \\n {'---'*20}\")\ndata_label_dict = {'image': [], 'target': []}\nfor i in tqdm(range(train.shape[0])):\n    data_label_dict['image'].append(\n        TRAIN_IMAGE_PATH + '/' +\n        train['id'][i][0] + '/' + \n        train['id'][i][1]+ '/' +\n        train['id'][i][2]+ '/' +\n        train['id'][i] + \".jpg\")\n    data_label_dict['target'].append(\n        train['landmark_id'][i])\n\n#Convert to dataframe\ntrain_pathlabel = pd.DataFrame(data_label_dict)\nprint(train_pathlabel.head())\n    \nprint(Fore.BLUE + f\"{'---'*20} \\n Mapping for Test Data \\n {'---'*20}\",Style.RESET_ALL)\ndata_label_dict = {'image': []}\nfor i in tqdm(range(submission.shape[0])):\n    data_label_dict['image'].append(\n        TEST_IMAGE_PATH + '/' +\n        submission['id'][i][0] + '/' + \n        submission['id'][i][1]+ '/' +\n        submission['id'][i][2]+ '/' +\n        submission['id'][i] + \".jpg\")\n\ntest_pathlabel = pd.DataFrame(data_label_dict)\nprint(test_pathlabel.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# list of unique landmark ids\ntrain.landmark_id.unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# count of unique landmark_ids\nprint(\"There are\", train.landmark_id.nunique(), \"landmarks in the training dataset\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# each class count-wise\ntrain.landmark_id.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Chceck File sizes of first 10 files"},{"metadata":{"trusted":true},"cell_type":"code","source":"files = train_pathlabel.image[:10]\nprint(Fore.BLUE + \"Shape of files from training dataset\",Style.RESET_ALL)\nfor i in range(10):\n    im = cv2.imread(files[i])\n    print(im.shape)\n\n\nprint(\"------------------------------------\")    \nprint(\"------------------------------------\")    \nprint(\"------------------------------------\")    \n\nfiles = test_pathlabel.image[:10]\nprint(Fore.BLUE + \"Shape of files from test dataset\",Style.RESET_ALL)\nfor i in range(10):\n    im = cv2.imread(files[i])\n    print(im.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Exploratory Data Analysis"},{"metadata":{},"cell_type":"markdown","source":"### Density plot for class distribution "},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (12, 8))\n\nsns.kdeplot(train['landmark_id'], color=\"yellow\",shade=True)\nplt.xlabel(\"LandMark IDs\")\nplt.ylabel(\"Probability Density\")\nplt.title('Class Distribution - Density plot')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Top 10 class categories"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (12,8))\n\ncount = train.landmark_id.value_counts().sort_values(ascending=False)[:10]\n\nsns.countplot(x=train.landmark_id,\n             order = train.landmark_id.value_counts().sort_values(ascending=False).iloc[:10].index)\n\nplt.xlabel(\"LandMark Id\")\nplt.ylabel(\"Frequency\")\nplt.title(\"Top 10 Classes in the Dataset\")\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Note that Landmark id '138982' has more than 6000 images, next top 9 clasess in this table have less than 2500 images\n"},{"metadata":{},"cell_type":"markdown","source":"### Viewing some landmarks "},{"metadata":{"trusted":true},"cell_type":"code","source":"top6 = train.landmark_id.value_counts().sort_values(ascending=False)[:6].index\n\nimages = []\n\nfor i in range(6):\n    img=cv2.imread(train_pathlabel[train_pathlabel.target == top6[i]]['image'].values[1])   \n    images.append(img)\n\nf, ax = plt.subplots(3,2, figsize=(20,15))\nfor i, img in enumerate(images):        \n        ax[i//2, i%2].imshow(img)\n        ax[i//2, i%2].axis('off')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Top 50 Class Categories"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (12,8))\n\ncount = train.landmark_id.value_counts().sort_values(ascending=False)[:50]\n\nsns.countplot(x=train.landmark_id,\n             order = train.landmark_id.value_counts().sort_values(ascending=False).iloc[:50].index)\n\nplt.xticks(rotation = 90)\n\nplt.xlabel(\"LandMark Id\")\nplt.ylabel(\"Frequency\")\nplt.title(\"Top 50 Classes in the Dataset\")\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"top50 = train.landmark_id.value_counts().sort_values(ascending=False).index[:50]\n\nimages = []\n\nfor i in range(50):\n    img=cv2.imread(train_pathlabel[train_pathlabel.target == top50[i]]['image'].values[1])   \n    images.append(img)\n\nf, ax = plt.subplots(10,5, figsize=(20,15))\nfor i, img in enumerate(images):        \n        ax[i//5, i%5].imshow(img)\n        ax[i//5, i%5].axis('off')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Bottom 10 Class Categories"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (10,6))\n\ncount = train.landmark_id.value_counts()[-10:]\n\nsns.countplot(x=train.landmark_id,\n             order = train_pathlabel.target.value_counts().iloc[-10:].index)\n\nplt.xlabel(\"LandMark Id\")\nplt.ylabel(\"Frequency\")\nplt.title(\"Bottom 10 Classes in the Dataset\")\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Just 2 images per class for the bottom 10 classes"},{"metadata":{},"cell_type":"markdown","source":"Observations from the whole analysis done above: \n*     There are 81313 unique landmark_ids \n*     There is only one landmark which has more than 6000 images\n*     Number of images per landmark_id ranges from 2 to 6272."},{"metadata":{},"cell_type":"markdown","source":"### Histogram of grayscale images\n* We will loaded the grayscale images here & generated its histogram\n* Since the images are stored in the form of a 2D ordered matrix we converted it to a 1D array using the ravel() method"},{"metadata":{"trusted":true},"cell_type":"code","source":"files = train_pathlabel.image[:4]\n\nfig = plt.figure(figsize = (20,9))\n\nfor i in range(4):\n    img=cv2.imread(files[i])   \n    plt.subplot(2,2,i+1)\n    plt.hist(img.ravel(), bins = 256,color = 'gold')\n    \nplt.suptitle(\"Histogram for Grayscale Images\",fontsize = 25)    \nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Histogram of grayscale images with bins = 8\n\nUsually, the range of intensity values of images is from [0–255] in 8bits representation(2⁸).\nBut images can be also represented using 2¹⁶, 2³² bits and so on. In such cases the intensity range is high and it is hard to represent each intensity value in a histogram.\n\nWe use binning to overcome the above problem. Here we quantize the range into several buckets. For example,\nIf we quantize 0-255 into 8 bins, here our bins will be: 0-31, 32-63, 64-95, 96-127, 128-159, 160-191, 192-223, 224-255"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (20,9))\n\nfor i in range(4):\n    img=cv2.imread(files[i])   \n    plt.subplot(2,2,i+1)\n    plt.hist(img.ravel(), bins = 8, color = \"coral\")\n\nplt.suptitle(\"Cumulative Histogram for Grayscale Images - Bin Size = 8\",fontsize = 25)    \nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Cumulative Histogram\n\nThe cumulative histogram is a special histogram that can be derived from the normal histogram. We find the counts of each intensity value from 0–255 and then add each subsequent counts."},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (20,9))\n\nfor i in range(4):\n    img=cv2.imread(files[i])   \n    plt.subplot(2,2,i+1)\n    plt.hist(img.ravel(), bins = 256,color = 'magenta',cumulative = True)\n\nplt.suptitle(\"Cumulative Histogram for Grayscale Images\",fontsize = 25)    \nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Histogram of Color Images\n\nIn color images, we have 3 color channels representing RGB. In Combined Color Histogram the intensity count is the sum of all three color channels."},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (20,9))\n\nfor i in range(4):\n    img=cv2.imread(files[i])   \n    plt.subplot(2,2,i+1)\n    plt.hist(img.ravel(), bins = 256, color = 'orange', )\n    plt.hist(img[:, :, 0].ravel(), bins = 256, color = 'red', alpha = 0.5)\n    plt.hist(img[:, :, 1].ravel(), bins = 256, color = 'Green', alpha = 0.5)\n    plt.hist(img[:, :, 2].ravel(), bins = 256, color = 'Blue', alpha = 0.5)\n    plt.xlabel('Intensity Value')\n    plt.ylabel('Count')\n    plt.legend(['Total', 'Red_Channel', 'Green_Channel', 'Blue_Channel'])\n\nplt.suptitle(\"Color Histograms\",fontsize = 25)    \nplt.show()","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":4}