{"cells":[{"cell_type":"markdown","metadata":{"_cell_guid":"ba643995-da99-e8ad-153d-8b598191b8ff"},"source":"# Updated Data exploration notebook  \n*We need to know the data we work with.*\n\nTrain data contains:\n\n - csv file with train images and labels \n - images without markers\n - image with markers\n - MismatchedTrainImages.txt "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"fe3fe2d5-8ca3-3134-77b4-4a6e7181ede3"},"outputs":[],"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nfrom subprocess import check_output\nprint(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n\n# Any results you write to the current directory are saved as output."},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"30690006-f2d3-6ac0-d57f-9ada03d23d01"},"outputs":[],"source":"import matplotlib.pylab as plt\n\ndef plt_st(l1,l2):\n    plt.figure(figsize=(l1,l2))\n    \ndef display_img(img_data, roi=None, no_colorbar=True, **kwargs):\n    if roi is not None:\n        # roi is [minx, miny, maxx, maxy]\n        x,y,xw,yh = roi\n        img_data = img_data[y:yh,x:xw,:] if len(img_data.shape) == 3 else img_data[y:yh,x:xw]\n\n    plt.imshow(img_data, **kwargs)\n    if not no_colorbar:\n        plt.colorbar(orientation='horizontal')    "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"5f6a23b1-4a89-d98f-bb74-9b0ff8a00201"},"outputs":[],"source":"!ls ../input/Train/*.jpg | wc -l\n!ls ../input/TrainDotted/*.jpg | wc -l\n!ls ../input/Test/*.jpg | wc -l"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"f473afed-6983-2040-20cd-abd5dc0ec164"},"outputs":[],"source":"import os\nDATA_PATH = \"../input\"\nTRAIN_PATH = os.path.join(DATA_PATH, 'Train')\nTRAIN_DOTTED_PATH = os.path.join(DATA_PATH, 'TrainDotted')\nTEST_PATH = os.path.join(DATA_PATH, 'Test')\nTRAIN_CSV_DATA = pd.read_csv(os.path.join(TRAIN_PATH, 'train.csv'))\n\ndef get_filename(image_id, image_type=''):\n    ext = 'jpg'\n    if image_type == '':\n        data_path = TRAIN_PATH\n    elif image_type == 'dotted':\n        data_path = TRAIN_DOTTED_PATH\n    elif image_type == 'test':\n        data_path = TEST_PATH\n    else:\n        raise Exception(\"Image type '%s' is not recognized\" % image_type) \n        \n    if not os.path.exists(data_path):\n        os.makedirs(data_path)\n   \n    return os.path.join(data_path, \"{}.{}\".format(image_id, ext))\n\n\nimport cv2\nfrom PIL import Image\n\ndef get_image_data(image_id, image_type=''):\n    fname = get_filename(image_id, image_type)\n    img = cv2.imread(fname)\n    assert img is not None, \"Failed to read image : %s, %s\" % (image_id, image_type)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    return img"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"319af627-1a64-cdab-de27-852263826109"},"outputs":[],"source":"IMAGE_IDS = !ls {TRAIN_PATH}/*.jpg\nIMAGE_IDS = [image_id[len(TRAIN_PATH)+1:-4] for image_id in IMAGE_IDS]\n\nTEST_IMAGE_IDS = !ls {TEST_PATH}/*.jpg\nTEST_IMAGE_IDS = [image_id[len(TEST_PATH)+1:-4] for image_id in TEST_IMAGE_IDS]"},{"cell_type":"markdown","metadata":{"_cell_guid":"6545ad07-8c9d-1284-4398-7a29ecbacc26"},"source":"## What a single image looks like"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a2819b5a-af14-85e9-1bc4-be033bce53f0"},"outputs":[],"source":"plt_st(10, 10)\nplt.subplot(121)\nplt.title(\"Train image\")\nplt.imshow(get_image_data(IMAGE_IDS[0]))\nplt.subplot(122)\nplt.title(\"Train image dotted\")\n_ = plt.imshow(get_image_data(IMAGE_IDS[0],'dotted'))"},{"cell_type":"markdown","metadata":{"_cell_guid":"ed11eb97-2624-bc29-eaaf-a6456fa025a9"},"source":"## What all available train images look like"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"82a80914-dea1-0408-34b1-81176907c9dd"},"outputs":[],"source":"tile_size = (256, 256)\nn = 5\nm = int(np.ceil(len(IMAGE_IDS) * 1.0 / n))\ncomplete_train_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\ncounter = 0\nfor i in range(m):\n    ys = i*(tile_size[1] + 2)\n    ye = ys + tile_size[1]\n    for j in range(n):\n        xs = j*(tile_size[0] + 2)\n        xe = xs + tile_size[0]\n        if counter == len(IMAGE_IDS):\n            break\n        image_id = IMAGE_IDS[counter]; counter+=1\n        img = get_image_data(image_id)\n        img = cv2.resize(img, dsize=tile_size)\n        img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n        complete_train_image[ys:ye, xs:xe, :] = img[:,:,:]\n    if counter == len(IMAGE_IDS):\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"04ebff82-a664-74c8-d498-750b605c5176"},"outputs":[],"source":"plt_st(15, 15)\nplt.imshow(complete_train_image)\nplt.title(\"Training dataset\")"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"cb4fe96b-2866-d99d-6049-c82bd4fbf8ec"},"outputs":[],"source":"tile_size = (256, 256)\nn = 5\nm = int(np.ceil(len(IMAGE_IDS) * 1.0 / n))\ncomplete_train_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\ncounter = 0\nfor i in range(m):\n    ys = i*(tile_size[1] + 2)\n    ye = ys + tile_size[1]\n    for j in range(n):\n        xs = j*(tile_size[0] + 2)\n        xe = xs + tile_size[0]\n        if counter == len(IMAGE_IDS):\n            break\n        image_id = IMAGE_IDS[counter]; counter+=1\n        img = get_image_data(image_id, 'dotted')\n        img = cv2.resize(img, dsize=tile_size)\n        img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n        complete_train_image[ys:ye, xs:xe, :] = img[:,:,:]\n    if counter == len(IMAGE_IDS):\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"842378d7-7ae0-4bd2-4514-044273217c49"},"outputs":[],"source":"plt_st(15, 15)\nplt.imshow(complete_train_image)\nplt.title(\"Training dotted dataset\")"},{"cell_type":"markdown","metadata":{"_cell_guid":"dfaaa298-2c93-b14c-f682-75a89a55ea26"},"source":"## and all available test images "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"1f1f7192-f42a-ab09-f457-c401331b2a5c"},"outputs":[],"source":"tile_size = (256, 256)\nn = 3\nm = int(np.ceil(len(TEST_IMAGE_IDS) * 1.0 / n))\ncomplete_train_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\ncounter = 0\nfor i in range(m):\n    ys = i*(tile_size[1] + 2)\n    ye = ys + tile_size[1]\n    for j in range(n):\n        xs = j*(tile_size[0] + 2)\n        xe = xs + tile_size[0]\n        if counter == len(TEST_IMAGE_IDS):\n            break\n        image_id = TEST_IMAGE_IDS[counter]; counter+=1\n        img = get_image_data(image_id, 'test')\n        img = cv2.resize(img, dsize=tile_size)\n        img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n        complete_train_image[ys:ye, xs:xe, :] = img[:,:,:]\n    if counter == len(TEST_IMAGE_IDS):\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"53526249-05d6-1567-8f75-ac4cdb3bc2ae"},"outputs":[],"source":"plt_st(15, 15)\nplt.imshow(complete_train_image)\nplt.title(\"Test dataset\")"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"8ecf4169-1ab1-2f63-04ce-ed65d07b26fd"},"outputs":[],"source":""},{"cell_type":"markdown","metadata":{"_cell_guid":"11cecd9a-b6d1-2c78-92f8-2a92d33a3a7a"},"source":"## Some images of TrainDotted are NOT exact copies with annotations\n\nThese are : \n\n```\ntrain_id\n3, 7, 9, 21, 30 ,34 ,71 ,81 ,89 ,97 ,151 ,184 ,215 ,234 ,242 ,268 ,290 ,311 ,331 ,344 ,380 ,384 ,406 ,421 ,469 ,475 ,490 ,499 ,507 ,530 ,531 ,605 ,607 ,614 ,621 ,638 ,644 ,687 ,712 ,721 ,767 ,779 ,781 ,794 ,800 ,811 ,839 ,840 ,869 ,882 ,901 ,903 ,905 ,909 ,913 ,927 ,946\n```"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"7136990d-133d-8884-931b-bd9c8e1b284d"},"outputs":[],"source":"roi = [1500, 1760, 2000, 2260]\nfor image_id in [IMAGE_IDS[4], IMAGE_IDS[8], IMAGE_IDS[10]]:\n    img1 = get_image_data(image_id)\n    img2 = get_image_data(image_id, 'dotted')\n    plt_st(12, 10)\n    plt.subplot(121)\n    display_img(img1, roi=roi)\n    plt.subplot(122)\n    display_img(img2, roi=roi)\n    plt.suptitle(\"Original VS Dotted, image id = %s\" % image_id)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"4c9625de-2d07-fc2f-0828-434bf99e8bb5"},"outputs":[],"source":""},{"cell_type":"markdown","metadata":{"_cell_guid":"1f18e2e9-3e0a-5d4d-6fb7-45b5ca209dd1"},"source":"## Animal marker detection\n\nInspired by this [kernel](https://www.kaggle.com/asymptote/noaa-fisheries-steller-sea-lion-population-count/initial-exploration)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"4a273b41-1733-7a8b-24fb-2ecb04458a7d"},"outputs":[],"source":"def get_n_animals(image_id):\n    df = TRAIN_CSV_DATA[TRAIN_CSV_DATA['train_id'] == int(image_id)]\n    df = df.drop('train_id', axis=1)\n    return df.sum(axis=1).values[0]"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"8ba24db1-8f59-e103-53a9-084ca6e03a9f"},"outputs":[],"source":"def create_train_mask(image_id):\n    img1 = get_image_data(image_id)\n    img2 = get_image_data(image_id, 'dotted')\n    black_mask = cv2.cvtColor(img2, cv2.COLOR_RGB2GRAY)\n    black_mask = cv2.medianBlur(black_mask, 5)\n    black_mask = (black_mask > 10).astype(np.uint8)    \n    img11 = img1 * np.expand_dims(black_mask, axis=2)    \n    diff = cv2.absdiff(img2, img11)\n    gray = cv2.cvtColor(diff, cv2.COLOR_RGB2GRAY)    \n    gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, \n                            kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)))\n    ret,mask = cv2.threshold(gray, 10, 255,cv2.THRESH_BINARY)\n    return mask, img1, img2\n\ndef filter_by_area(cnts, min_area=2.0**2):\n    out = []\n    for c in cnts:\n        if cv2.contourArea(c) > min_area:\n            out.append(c)\n    return out"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"aa520934-ece7-e2d9-affa-667b700a7670"},"outputs":[],"source":"# red: adult males\n# magenta: subadult males\n# brown: adult females\n# blue: juveniles\n# green: pups\n\nMARKER_COLORS = {\n    (255, 0, 0): 'adult males - red',\n    (255, 0, 255): 'subadult males - magenta',\n    (127, 69, 0): 'adult females - brown',\n    (0, 0, 255): 'juveniles - blue',\n    (0, 255, 0): 'pups - green'    \n}\n    "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"226135aa-e4ca-691f-776c-264db7080a7d"},"outputs":[],"source":"def find_markers(image_id):\n    out = []\n    mask, img, img_dotted  = create_train_mask(image_id)\n    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]\n    cnts = filter_by_area(cnts)\n    for c in cnts:\n        out.append(cv2.minEnclosingCircle(c))\n    return out, img, img_dotted\n\n\ndef find_closest_marker_color(p, colors):\n    colors = np.array(colors)\n    p = np.array(p)\n    err = np.sum(np.abs(colors - p[None, :]), axis=1)\n    return colors[np.argmin(err)]"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"6737b6c5-e7c9-17f8-8740-562a3423b402"},"outputs":[],"source":"image_id = IMAGE_IDS[0] \nmarkers, img, img_dotted = find_markers(image_id)\n\nprint(\"{} markers found\".format(len(markers)))\nprint(\"{} sea lions\".format(get_n_animals(image_id)))\n\nfor i, marker in enumerate(markers):\n    (x, y), r = marker\n    x = int(x)\n    y = int(y)    \n    p = np.mean(img_dotted[y-1:y+1, x-1:x+1, :],axis=(0, 1))\n    \n    roi = [x - 50, y - 50, x + 50, y + 50]\n    plt_st(12, 6)\n    plt.subplot(121)\n    display_img(img, roi=roi)\n    plt.subplot(122)\n    display_img(img_dotted, roi=roi)\n\n    c = find_closest_marker_color(p, list(MARKER_COLORS.keys() ) ) \n    plt.suptitle(\"{}\".format(MARKER_COLORS[tuple(c)]) )\n    \n    if i == 10:\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"c9e1e32d-bb54-39ab-99ee-b8248f8b9e45"},"outputs":[],"source":"image_id = IMAGE_IDS[1] \nmarkers, img, img_dotted = find_markers(image_id)\n\nprint(\"{} markers found\".format(len(markers)))\nprint(\"{} sea lions\".format(get_n_animals(image_id)))\n\nfor i, marker in enumerate(markers):\n    (x, y), r = marker\n    x = int(x)\n    y = int(y)    \n    p = np.mean(img_dotted[y-1:y+1, x-1:x+1, :],axis=(0, 1))\n    \n    roi = [x - 50, y - 50, x + 50, y + 50]\n    plt_st(12, 6)\n    plt.subplot(121)\n    display_img(img, roi=roi)\n    plt.subplot(122)\n    display_img(img_dotted, roi=roi)\n\n    c = find_closest_marker_color(p, list(MARKER_COLORS.keys() ) ) \n    plt.suptitle(\"{}\".format(MARKER_COLORS[tuple(c)]) )\n    \n    if i == 10:\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a623c95d-073c-e1bd-dfc0-88e861d71ee2"},"outputs":[],"source":"help(cv2.Canny)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"260d37ad-a0ae-5c11-132c-9a83f40ba75c"},"outputs":[],"source":"def compute_edges(img):    \n    edges = cv2.Canny(img, 170, 210)\n    return edges"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"840e4f8b-dedc-9ce0-2019-ded4f794f420"},"outputs":[],"source":"image_id = IMAGE_IDS[1] \nimg = get_image_data(image_id)\nedges = compute_edges(img)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"8b4748c0-a6ed-dfc5-ec53-19887c04dc54"},"outputs":[],"source":"help(cv2.Laplacian)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"1f62081d-efff-1301-e0ea-2d3df6824153"},"outputs":[],"source":"def get_roi(img, x, y, size):\n    img_roi = img[y-size:y+size, x-size:x+size, :] if len(img.shape) == 3 else img[y-size:y+size, x-size:x+size]\n    return img_roi\n\nproc = img\nproc = cv2.Laplacian(proc, cv2.CV_8U, ksize=1)\nproc = cv2.cvtColor(proc, cv2.COLOR_RGB2GRAY)\n\nx = 3619\ny = 3609\nroi_size = 50\nimg_roi = get_roi(proc , x, y, roi_size)\nshape = img_roi.shape\nmask = np.zeros((shape[0] + 2, shape[1] + 2), dtype=np.uint8)\nmask[1:-1,1:-1] = get_roi(edges, x, y, roi_size)\n\n\n_, img2, mask2, _ = cv2.floodFill(img_roi, mask, \n                                  seedPoint=(roi_size-1, roi_size-1), \n                                  newVal=255,\n                                  loDiff=(50, 50, 50), \n                                  upDiff=(50, 50, 50), \n                                  flags= 4 | cv2.FLOODFILL_FIXED_RANGE | cv2.FLOODFILL_MASK_ONLY | 255 << 8)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"7505f19e-13a6-9e06-2fb6-c960a9ddf51e"},"outputs":[],"source":"plt_st(12, 6)\nplt.subplot(121)\ndisplay_img(img_roi)\nplt.subplot(122)\ndisplay_img(mask2)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"e28c2257-9a8e-f854-e8ba-31713073280c"},"outputs":[],"source":"def segment_sea_lion(img, seed_point):\n    pass"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"737ce37a-7c1b-c281-87d1-afa9b65bd2a0"},"outputs":[],"source":"image_id = IMAGE_IDS[1] \nmarkers, img, img_dotted = find_markers(image_id)\n\nprint(\"{} markers found\".format(len(markers)))\nprint(\"{} sea lions\".format(get_n_animals(image_id)))\n\nfor i, marker in enumerate(markers):\n    (x, y), r = marker\n    x = int(x)\n    y = int(y)    \n    p = np.mean(img_dotted[y-1:y+1, x-1:x+1, :],axis=(0, 1))\n    \n    edges = compute_edges(img)\n    \n    roi = [x - 50, y - 50, x + 50, y + 50]\n    print(roi, (x, y))\n    plt_st(12, 6)\n    plt.subplot(131)\n    display_img(img, roi=roi)\n    plt.subplot(132)\n    display_img(img_dotted, roi=roi)\n    plt.subplot(133)\n    display_img(img + 255 * edges[:,:,None], roi=roi)\n\n    c = find_closest_marker_color(p, list(MARKER_COLORS.keys() ) ) \n    plt.suptitle(\"{}\".format(MARKER_COLORS[tuple(c)]) )\n    break\n    if i == 10:\n        break"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"4a1d9a46-bda5-9b86-44ad-f269e9d10b89"},"outputs":[],"source":""},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"b10d8aae-e2b4-2ae3-0467-3c61ad26e374"},"outputs":[],"source":""}],"metadata":{"_change_revision":0,"_is_fork":false,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.0"}},"nbformat":4,"nbformat_minor":0}