{"cells":[{"metadata":{},"cell_type":"markdown","source":"Reference: https://www.kaggle.com/ekhtiar/eda-find-me-in-the-clouds, please also upvote this great kernel if you find it's useful.\nThis kernel shows basic eda about this competition, cause I decided to use this competition as a final project for one of my courses, so I will continue working and hope for your feedback, I will appreciate it."},{"metadata":{},"cell_type":"markdown","source":"# Import Libraries & Functions"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport warnings\nimport cv2\nimport random\nfrom matplotlib import pyplot as plt\n\n%matplotlib inline\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.getcwd())\nprint(os.listdir('../input'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show(img):\n#     plt.figure()\n    plt.imshow(img)\n#     plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def rle_to_mask(rle_string, img):\n    \n    rows, cols = img.shape[0], img.shape[1]\n    img = np.zeros(rows*cols, dtype=np.uint8)\n\n    rle_numbers = [int(x) for x in rle_string.split(' ')]\n    rle_pairs = np.array(rle_numbers).reshape(-1,2)\n\n    for index, length in rle_pairs:\n        index -= 1\n        img[index:index+length] = 255\n    img = img.reshape(cols,rows)\n    img = img.T\n    img = image = np.expand_dims(img, axis=2)\n    \n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def ignore_background(img_mask, img_origin):\n    assert img_mask.shape == img_mask.shape\n    \n    result = img_mask.copy()\n    result[np.where(img_mask==255)] = img_origin[np.where(img_mask==255)]\n    \n    return result","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv = pd.read_csv('../input/understanding_cloud_organization/train.csv')\nsub_csv = pd.read_csv('../input/understanding_cloud_organization/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv = train_csv.fillna(-1)\ntrain_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv['ImageId'] = train_csv['Image_Label'].apply(lambda x: x.split('_')[0])\ntrain_csv['Label'] = train_csv['Image_Label'].apply(lambda x: x.split('_')[1])\ntrain_csv = train_csv.drop('Image_Label', axis=1)\ntrain_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Total', len(train_csv['ImageId'].unique()),'Images for', len(train_csv['Label'].unique()), 'Types.')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Analysis Data"},{"metadata":{},"cell_type":"markdown","source":"To begin with, I want to see the balance of each type."},{"metadata":{"trusted":true},"cell_type":"code","source":"fish = len(train_csv[train_csv['Label']=='Fish'][train_csv['EncodedPixels']!= -1])\nflower = len(train_csv[train_csv['Label']=='Flower'][train_csv['EncodedPixels']!= -1])\ngravel = len(train_csv[train_csv['Label']=='Gravel'][train_csv['EncodedPixels']!= -1])\nsugar = len(train_csv[train_csv['Label']=='Sugar'][train_csv['EncodedPixels']!= -1])\nprint('The amount of Fish:{0}, Flower:{1}, Gravel:{2}, Sugar:{3} .'.format(fish, flower, gravel, sugar))\nprint('Totally {} valid Images.'.format(fish+flower+gravel+sugar))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.title(\"Total amount of images each type.\")\nplt.bar([1,2,3,4],[fish, flower, gravel, sugar], tick_label=['Fish', 'Flower', 'Graver', 'Sugar'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The balance seems ok, so then I want to see how many types each image has."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_csv[train_csv['EncodedPixels']!=-1]\ntrain_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"types_per_image = train_df.groupby(by='ImageId', as_index=False).agg({'EncodedPixels': pd.Series.nunique})['EncodedPixels']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"per = np.histogram(list(types_per_image), bins=range(1, 6))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.title(\"Histogram of types per image.\")\nplt.bar([1,2,3,4], per[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"So, most of the images contain 2 types, and only 266 images contain all of 4 types."},{"metadata":{},"cell_type":"markdown","source":"# Visualize Mask"},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_DIR = '../input/understanding_cloud_organization/train_images/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's test one image first."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = cv2.imread(BASE_DIR + train_df['ImageId'][7])\nimg = cv2.resize(img, (512, 512))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show(img);plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"horizontal_img = cv2.flip( img, 0 )\nvertical_img = cv2.flip( img, 1 )\nboth_img = cv2.flip( img, -1 )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"(h, w) = img.shape[:2] #10\ncenter = (w // 2, h // 2)\nM = cv2.getRotationMatrix2D(center, 40, 1.0) #12\nrotated = cv2.warpAffine(img, M, (w, h))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nlab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)\n\nlab_planes = cv2.split(lab)\n\nclahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))\n\nlab_planes[0] = clahe.apply(lab_planes[0])\n\nlab = cv2.merge(lab_planes)\n\nbgr = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(bgr);plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = cv2.imread(BASE_DIR + train_df['ImageId'][0])\nimg_mask = rle_to_mask(train_df['EncodedPixels'][0], img)\nimg_new0 = ignore_background(img_mask, img)\nimg_mask = rle_to_mask(train_df['EncodedPixels'][1], img)\nimg_new1 = ignore_background(img_mask, img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_mask.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.subplots(figsize=(15, 6))\nplt.subplot(1,3,1); show(img);plt.title('orginal image');\nplt.subplot(1,3,2); show(img_new0);plt.title('Fish part');\nplt.subplot(1,3,3); show(img_new1);plt.title('Flower part');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Then I want to see more data."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df.reset_index(drop=True)\nfor i in range(100):\n    index = random.randint(0, 11835)\n    img = cv2.imread(BASE_DIR + train_df['ImageId'][index])\n    plt.subplots(figsize=(15, 6))\n    plt.subplot(1, 3, 1); show(img);\n    plt.title('Origin Image. Index: {} Type: {}'.format(index, train_df['Label'][index]))\n    plt.subplot(1, 3, 2); show(rle_to_mask(train_df['EncodedPixels'][index], img));\n    plt.title('Mask. Index: {} Type: {}'.format(index, train_df['Label'][index]))\n    plt.subplot(1, 3, 3); show(ignore_background(rle_to_mask(train_df['EncodedPixels'][index], img), img));\n    plt.title('Masked Image. Index: {} Type: {}'.format(index, train_df['Label'][index]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we can see, most of the masks are rectangular, or likely to be shaped as a rectangle. One thing that matters is that 'black zone', this always break the mask and should be regard as noise.\nIn this occation, I considere two ways to solve the problem, Image Segmentation or Object Detection, based on my experience, the first method is more likely to occur overfit while the second is underfit."},{"metadata":{},"cell_type":"markdown","source":"Then I want to see if one pixel could have multi classes."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_id = list(train_df['ImageId'].unique())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"warm = []\nfor x in image_id:\n    img = cv2.imread(BASE_DIR + x)\n    tmp = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)\n    types = list(train_df[train_df['ImageId']==x]['EncodedPixels'])\n    for y in types:\n        print(rle_to_mask(y, img).shape)\n        tmp = tmp + rle_to_mask(y, img)/255.0\n    warm.append(np.max(tmp))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.title('Amount of Types per Pixel has')\nplt.bar([1,2,3,4], np.histogram(warm, bins=range(1, 6))[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From here we can see, most images contain pixels that belong to 2 classes or less,and few pixels has 3 classes or more.<!-- So I think it's better to train models for each type, and then conbine them together. -->"},{"metadata":{},"cell_type":"markdown","source":"Till now, I think I have done most of eda, https://www.kaggle.com/ekhtiar/eda-find-me-in-the-clouds?scriptVersionId=19089157 a great kernel, also contains some useful information I didn't work with. \nThen I will start to build my own model."},{"metadata":{},"cell_type":"markdown","source":"By the way, because this will be used as my course project, so I do willing to know your feedback and suggestions, which will help to improve my project quality. I will appreciate it if you can help, thanks. <!--And if anyone want to team up, pls send me the message.-->"},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"import pandas as pd\nensemble = pd.read_csv(\"../input/ensemble/ensemble.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ensemble.head(30)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"result = cv2.imread('../input/understanding_cloud_organization/test_images/969f34b.jpg')\nresult = cv2.resize(result, (525, 350))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_mask = rle_to_mask(ensemble['EncodedPixels'][1], result)\nimg_new0 = ignore_background(img_mask, result)\nimg_mask = rle_to_mask(ensemble['EncodedPixels'][3], result)\nimg_new1 = ignore_background(img_mask, result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.subplots(figsize=(15, 6))\nplt.subplot(1,3,1); show(result);plt.title('orginal image');\nplt.subplot(1,3,2); show(img_new0);plt.title('Flower part');\nplt.subplot(1,3,3); show(img_new1);plt.title('Sugar part');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"result = cv2.imread('../input/understanding_cloud_organization/test_images/5a61caf.jpg')\nresult = cv2.resize(result, (525, 350))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_mask = rle_to_mask(ensemble['EncodedPixels'][21], result)\nimg_new0 = ignore_background(img_mask, result)\nimg_mask = rle_to_mask(ensemble['EncodedPixels'][22], result)\nimg_new1 = ignore_background(img_mask, result)\nimg_mask = rle_to_mask(ensemble['EncodedPixels'][23], result)\nimg_new2 = ignore_background(img_mask, result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.subplots(figsize=(15, 6))\nplt.subplot(1,4,1); show(result);plt.title('orginal image');\nplt.subplot(1,4,2); show(img_new0);plt.title('Flower part');\nplt.subplot(1,4,3); show(img_new1);plt.title('Gravel part');\nplt.subplot(1,4,4); show(img_new2);plt.title('Sugar part');","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":1}