{"cells":[{"metadata":{"_cell_guid":"892cd00e-ba7c-4b8a-8d98-32e505e39120","_uuid":"b14dbf87581a1b2b5fe288c50f82657a97a39043"},"cell_type":"markdown","source":"This kernel visualizes data from the [2018 Data Science Bowl Dataset](https://www.kaggle.com/c/data-science-bowl-2018).  The training set contains images of biological cell nuclei and masks that annotate where each cell nucleus is."},{"metadata":{"_cell_guid":"cf333519-d85f-435e-9a02-beb59e6cc7e3","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"9968cf96234d72157770dea9b97d3cf944177bcf","collapsed":true,"trusted":true},"cell_type":"code","source":"TRAIN_PATH = '../input/stage1_train/'\nTEST_PATH = '../input/stage1_test/'\nFIG_SIZE = (20, 30)","execution_count":1,"outputs":[]},{"metadata":{"_cell_guid":"950a4a6c-5ac6-434f-abbe-37dc2061ea16","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"c8f02571497443180119f9d3a7062fe5da7c97d3","collapsed":true,"trusted":true},"cell_type":"code","source":"import math\nimport itertools\nimport os\nimport numpy as np\nimport skimage.io as io\nimport pandas as pd\nfrom scipy import ndimage\nimport matplotlib\nfrom matplotlib import pyplot as plt\nfrom matplotlib import gridspec\n%matplotlib inline\nimport warnings\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')","execution_count":2,"outputs":[]},{"metadata":{"_cell_guid":"5712c60d-c7d3-4325-9b99-08c4e6d0624d","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"ae7ab9fea1138da9d4494ee0efd9ab059fbb0bd2","collapsed":true,"trusted":true},"cell_type":"code","source":"def hsv_to_rgb(h, s, v):\n    h -= math.floor(h)\n    h = h * 6\n    if h < 1:\n        [r, g, b] = [1, h, 0]\n    elif h < 2:\n        [r, g, b] = [2 - h, 1, 0]\n    elif h < 3:\n        [r, g, b] = [0, 1, h - 2]\n    elif h < 4:\n        [r, g, b] = [0, 4 - h, 1]\n    elif h < 5:\n        [r, g, b] = [h - 4, 0, 1]\n    else:\n        [r, g, b] = [1, 0, 6 - h]\n    return [((r - 0.5) * s + 0.5) * v, ((g - 0.5) * s + 0.5) * v, ((b - 0.5) * s + 0.5) * v]\n\nhash_colorize = np.array([[0, 0, 0] if i == 0 else\n                              hsv_to_rgb(((i + 1) % 17)/17,\n                                         ((i + 1) % 3)/3 / 2 + 0.5,\n                                         ((i + 1) % 5)/5 * 2/3 + 1/3)\n                          for i in range(256)])\n\ndef mask_to_edges(mask):\n    mask_edges = np.zeros(mask.shape).astype(np.uint8)\n    for ii in range(1, mask.max() + 1):\n        submask = mask.copy()\n        submask[submask != ii] = 0\n        submask[submask == ii] = 1\n        submask_edges = submask - ndimage.binary_erosion(submask, structure=np.ones((5,5)))\n        mask_edges += submask_edges * ii\n    return mask_edges\n\ndef visualize_mask(mask, img=None, edges=True, fill=True):\n    if fill:\n        if img is None:\n            img = mask.copy()\n            img[img > 0] = 1\n        img = np.multiply(np.repeat(np.reshape(img, img.shape + (1,)), 3, 2), hash_colorize[mask])\n    else:\n        if img is None:\n            img = np.zeros(mask.shape)\n        img = np.repeat(np.reshape(img, img.shape + (1,)), 3, 2)\n    if edges:\n        img = np.clip(img + hash_colorize[mask_to_edges(mask)], 0, 1)\n    return img","execution_count":3,"outputs":[]},{"metadata":{"_cell_guid":"a8932bbd-ed4d-4b46-a362-c857914da0b2","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"405084b80debd913e611f6b3128e65579b7c8b11","collapsed":true,"trusted":true},"cell_type":"code","source":"def remove_alpha(img):\n    return img[:, :, 0:3]\n\ndef grayscale(img):\n    if img.shape[2] == 4:\n        img = remove_alpha(img)\n    return img.mean(axis=2)\n\ndef normalize(img):\n    if len(img.shape) == 3 and img.shape[2] == 4:\n        img = remove_alpha(img)\n    img_max = img.max()\n    img_min = img.min()\n    img = (img - img_min) / (img_max - img_min)\n    return img\n\ndef flatten_masks(masks):\n    mask = np.zeros(masks[0].shape).astype(np.uint8)\n    for ii, submask in enumerate(masks, 1):\n        submask[submask > 0] = 1\n        mask += submask * ii\n    return mask\n\nclass NucleiDataset():\n    def __init__(self, path, transform = None):\n        self.path = path\n        self.transform = transform\n        self.ids = next(os.walk(path))[1]\n\n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, idx):\n        id = self.ids[idx]\n        return self.get(id)\n    \n    def get(self, id):\n        path = self.path + id\n        image = io.imread(path + \"/images/\" + id + \".png\")\n        masks = []\n        mask_path = path + \"/masks/\"\n        for mask in next(os.walk(mask_path))[2]:\n            masks.append(io.imread(mask_path + mask))\n        sample = {\"id\": id, \"image\": image, \"masks\": masks}\n        if self.transform:\n            self.transform(sample)\n        return sample        \n\ndef normalize_and_flatten(sample):\n    sample[\"image\"] = normalize(grayscale(sample[\"image\"]))\n    sample[\"mask\"] = flatten_masks(sample[\"masks\"])\n    del sample[\"masks\"]\n\ntrain_set = NucleiDataset(TRAIN_PATH)\ntest_set = NucleiDataset(TEST_PATH)","execution_count":4,"outputs":[]},{"metadata":{"_cell_guid":"672ddaef-a75c-4795-8c8c-17a39afecfb1","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"6067dd3808892d1725fba90e308827843e489d3f","collapsed":true,"trusted":true},"cell_type":"code","source":"def plot_image(fig, sample, plot_spec):\n    image = sample[\"image\"]\n\n    inner = gridspec.GridSpecFromSubplotSpec(1, 2,\n                    subplot_spec=plot_spec, wspace=0.1, hspace=0.1)\n    for j in range(2):\n        ax = plt.Subplot(fig, inner[j])\n        if j == 0:\n            ax.imshow(normalize(image))\n        else:\n            ax.imshow(visualize_mask(flatten_masks(sample[\"masks\"]), img=normalize(grayscale(image))))\n        ax.set_xticks([])\n        ax.set_yticks([])\n        fig.add_subplot(ax)","execution_count":5,"outputs":[]},{"metadata":{"_cell_guid":"34d6520c-799a-4b7a-929c-4cd77230f8df","_uuid":"b7e4c9559ce4067aac9609cfbf59690ed363d62c"},"cell_type":"markdown","source":"# Overview\n\nBelow, we see the first 32 entries in the training set.  Each (horizontal) pair of images shows first the input image and then the associated masks, with each cell nucleus highlighted in a different color.  "},{"metadata":{"_cell_guid":"14bac0bf-f10e-42a8-b132-e1333de1e54a","_kg_hide-input":true,"_uuid":"fef4dc19933a53cf8490a51dad598560a969acd6","collapsed":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(FIG_SIZE[1], FIG_SIZE[1]))\nouter = gridspec.GridSpec(8, 4, wspace=0.2, hspace=0.2)\n\nfor (i, sample) in enumerate(itertools.islice(train_set, 32)):\n    plot_image(fig, sample, outer[i])","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"d92ddab6-9009-48e8-9d28-b971744878ee","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"7a8ca4c928b8a81676893f72381bd88269e6fb73","collapsed":true,"trusted":true},"cell_type":"code","source":"image_ids = []\nimage_sizes = []\nfor sample in train_set:\n    image = sample[\"image\"]\n    image_ids.append(sample[\"id\"])\n    image_sizes.append([image.shape[1], image.shape[0]])\nimage_ids = np.array(image_ids)\nimage_sizes = np.array(image_sizes)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"b3ff4c84-7072-4ad0-a153-80ace329c6df","_uuid":"453b7aa36afa965716696595b356c80eeec2fca3"},"cell_type":"markdown","source":"# Image Size\n\nThe table below shows the width and height of each sample in the training set."},{"metadata":{"_cell_guid":"329de2bd-1302-44ce-a3d7-e78d44200e90","_kg_hide-input":true,"_uuid":"02b9b35354006f488ce3dfd4225317e9636636a9","collapsed":true,"trusted":true},"cell_type":"code","source":"images = np.rec.fromarrays((image_ids, image_sizes[:, 0], image_sizes[:, 1]),\n                           dtype=[('id', image_ids.dtype), ('w', int), ('h', int)])\npd.DataFrame.from_records(images, index=('id'))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"d25bbf53-2965-4dea-a56b-4c716012ce27","_uuid":"c220f9717bdf47ed6c1e1657e6c7844b5499391c"},"cell_type":"markdown","source":"Here are some statistics on the size of the images in the training set."},{"metadata":{"_cell_guid":"7362b22a-a4c1-4f35-9734-55a7922415ee","_kg_hide-input":true,"_uuid":"e5d1b25ed63d0b811775baf9c92b19b9337559aa","collapsed":true,"trusted":true},"cell_type":"code","source":"print(\"Range: (%d - %d) x (%d - %d)\" % (images.w.min(), images.w.max(), images.h.min(), images.h.max()))\nprint(\"Mean: %d x %d\" % (images.w.mean(), images.h.mean()))\naspect_ratio = images.w / images.h\ndef aspect_ratio_to_str(ratio):\n    if ratio >= 1:\n        return \"%f : 1\" % (ratio,)\n    else:\n        return \"1 : %f\" % (1 / ratio,)\nprint(\"Aspect ratio range: (%s) - (%s)\" % (aspect_ratio_to_str(aspect_ratio.min()), aspect_ratio_to_str(aspect_ratio.max())))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"37cc6e76-3272-48b9-8fcf-0406627121be","_uuid":"3fe0e55cf5fbf5003cc9dc55f0af5bc5013c2f7a"},"cell_type":"markdown","source":"These are the smallest (left) and largest (right) samples (measured by area) in the training set.  Note that despite the fact that the sample on the right is much higher resolution and so is scaled down, the cell nuclei still appear about the same size, meaning that the nuclei are (in pixel terms) quite a bit larger."},{"metadata":{"_cell_guid":"00f3f5b0-e94a-458d-9c98-875f5ae5591e","_kg_hide-input":true,"_uuid":"0166b8df97b1eaac78dd523251345ecbb0768309","collapsed":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(FIG_SIZE[1], FIG_SIZE[1]))\nouter = gridspec.GridSpec(1, 2, wspace=0.2, hspace=0.2)\n\nsmallest_image = images[(images.w * images.h).argmin()]\nbiggest_image = images[(images.w * images.h).argmax()]\n\nplot_image(fig, train_set.get(smallest_image.id), outer[0])\nplot_image(fig, train_set.get(biggest_image.id), outer[1])","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"96f088d6-c1a2-4427-a84b-58bc1fe93be1","_uuid":"aaf0e7043247d105a5c68926f5522906f25378f3"},"cell_type":"markdown","source":"These are the samples with the lowest (left) and highest (right) aspect ratio in the training set."},{"metadata":{"_cell_guid":"be44b765-befb-4094-91b7-e996be694904","_kg_hide-input":true,"_uuid":"fb1c6fc5370ce0910d9b469126247f9addb975f7","collapsed":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(FIG_SIZE[1], FIG_SIZE[1]))\nouter = gridspec.GridSpec(1, 2, wspace=0.2, hspace=0.2)\n\nlowest_aspect_image = images[(images.w / images.h).argmin()]\nhighest_aspect_image = images[(images.w / images.h).argmax()]\n\nplot_image(fig, train_set.get(lowest_aspect_image.id), outer[0])\nplot_image(fig, train_set.get(highest_aspect_image.id), outer[1])","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"e3f66a89-af37-4124-9047-494410ea9e0e","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"8f9a3230b7b36b946feb85ddc966e9fc6308242a","trusted":true,"collapsed":true},"cell_type":"code","source":"mask_ids = []\nmask_idcs = []\nmask_bounds = []\nmask_pixel_counts = []\nmask_overlap_counts = []\nfor sample in train_set:\n    image = sample[\"image\"]\n    accumulated_mask = np.zeros(image.shape[0:len(image.shape)-1])\n    for (mask_idx, mask) in enumerate(sample[\"masks\"]):\n        mask_ids.append(sample[\"id\"])\n        mask_idcs.append(mask_idx)\n        x_positions = np.any(mask, axis=0).nonzero()[0]\n        y_positions = np.any(mask, axis=1).nonzero()[0]\n        mask_bounds.append([int(x_positions.min()), int(y_positions.min()), int(x_positions.max()), int(y_positions.max())])\n        mask_pixel_counts.append(int(np.count_nonzero(mask)))\n        mask_overlap_counts.append(int(np.count_nonzero(accumulated_mask * mask)))\n        accumulated_mask += mask","execution_count":8,"outputs":[]},{"metadata":{"_cell_guid":"62b7505f-d6f9-473f-9bdb-1af7b82232da","_uuid":"f72830cfd61998fe2ab31f0d1960ab1712b4823a"},"cell_type":"markdown","source":"# Cell Nuclei Sizes\nThe table below shows, for each sample and each cell nucleus mask in that sample, the bounding box of the nucleus, the count of pixels in the mask, and hence the width, height, area, density and overlap with other masks."},{"metadata":{"_cell_guid":"e908db68-27de-45e7-a715-1863e787c1f9","_kg_hide-input":true,"_uuid":"6de8bd6e1625431690fac8dac46f8ae8f894fa9a","trusted":true},"cell_type":"code","source":"mask_ids = np.array(mask_ids)\nmask_idcs = np.array(mask_idcs)\nmask_bounds = np.array(mask_bounds)\nmask_pixel_counts = np.array(mask_pixel_counts)\nmask_overlap_counts = np.array(mask_overlap_counts)\nwidth = mask_bounds[:, 2] - mask_bounds[:, 0] + 1\nheight = mask_bounds[:, 3] - mask_bounds[:, 1] + 1\narea = width * height\ndensity = mask_pixel_counts / area\nmasks = np.rec.fromarrays((mask_ids, mask_idcs, mask_bounds[:, 0], mask_bounds[:, 1], mask_bounds[:, 2], mask_bounds[:, 3], mask_pixel_counts, width, height, area, density, mask_overlap_counts),\n                          dtype=[('id', mask_ids.dtype), ('mask', int), ('x1', int), ('y1', int), ('x2', int), ('y2', int), ('count', int), ('w', int), ('h', int), ('area', int), ('density', float), ('overlap', int)])\npd.DataFrame.from_records(masks, index=('id', 'mask'))","execution_count":9,"outputs":[]},{"metadata":{"_cell_guid":"cca8b663-0cef-410b-ba34-2e2ed150db35","_uuid":"ee50f150dcf6f160328b4e16ad41a67606891c4d"},"cell_type":"markdown","source":"Here are some statistics on the sizes of nuclei in the training set."},{"metadata":{"_cell_guid":"b881f4f4-78a2-4bda-94ad-3365110169ae","_kg_hide-input":true,"_uuid":"e3fdc31196f6d21e7958e4c62b1fbc4c7b527eba","trusted":true},"cell_type":"code","source":"print(\"Range: (%d - %d) x (%d - %d)\" % (masks.w.min(), masks.w.max(), masks.h.min(), masks.h.max()))\nprint(\"Mean: %d x %d\" % (masks.w.mean(), masks.h.mean()))\naspect_ratio = masks.w / masks.h\ndef aspect_ratio_to_str(ratio):\n    if ratio >= 1:\n        return \"%f : 1\" % (ratio,)\n    else:\n        return \"1 : %f\" % (1 / ratio,)\nprint(\"Aspect ratio range: (%s) - (%s)\" % (aspect_ratio_to_str(aspect_ratio.min()), aspect_ratio_to_str(aspect_ratio.max())))\nprint(\"Mean density within bounds: %f%%\" % (100. * masks.count.sum() / (masks.w * masks.h).sum(),))\nprint(\"Mean density across all pixels: %f%%\" % (100. * masks.count.sum() / (images.w * images.h).sum(),))\nprint(\"Total mask overlap: %d\" % (masks.overlap.sum()))","execution_count":11,"outputs":[]},{"metadata":{"_cell_guid":"9178e362-b5ce-4fec-845c-f59e5b964b8e","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"370e8ef5eb2bf484e7a0df12dd6658144699b9dd","collapsed":true,"trusted":true},"cell_type":"code","source":"# Clip a mask out\ndef clip(img, mask_rec, border, pad=False):\n    x1 = max(mask_rec.x1-border, 0)\n    x2 = min(mask_rec.x2+border, img.shape[1])\n    y1 = max(mask_rec.y1-border, 0)\n    y2 = min(mask_rec.y2+border, img.shape[0])\n    img = img[y1:y2, x1:x2]\n    if pad:\n        img = np.pad(img, ((y1-mask_rec.y1+border, mask_rec.y2+border-y2), (x1-mask_rec.x1+border, mask_rec.x2+border-x2), (0, 0)), mode='edge')\n    return img\n\n# Remove any padding added by previous clip\ndef reclip(img, clipped, mask_rec, border):\n    x1 = max(mask_rec.x1-border, 0)\n    x2 = min(mask_rec.x2+border, img.shape[1])\n    y1 = max(mask_rec.y1-border, 0)\n    y2 = min(mask_rec.y2+border, img.shape[0])\n    clipped = clipped[y1-mask_rec.y1+border:clipped.shape[0] - mask_rec.y2-border+y2, x1-mask_rec.x1+border:clipped.shape[1] - mask_rec.x2-border+x2]\n    return clipped\n\ndef plot_mask(fig, dataset, mask_rec, plot_spec):\n    sample = dataset.get(mask_rec.id)\n    image = sample[\"image\"]\n    mask = sample[\"masks\"][mask_rec.mask]\n\n    inner = gridspec.GridSpecFromSubplotSpec(1, 2,\n                    subplot_spec=plot_spec, wspace=0.1, hspace=0.1)\n    for j in range(2):\n        ax = plt.Subplot(fig, inner[j])\n        if j == 0:\n            ax.imshow(clip(normalize(image), mask_rec, 5))\n        else:\n            ax.imshow(reclip(image,\n                    visualize_mask(clip(np.expand_dims(flatten_masks(sample[\"masks\"]), 2), mask_rec, 5, pad=True)[..., 0],\n                                   img=normalize(grayscale(clip(image, mask_rec, 5, pad=True)))), mask_rec, 5))\n        ax.set_xticks([])\n        ax.set_yticks([])\n        fig.add_subplot(ax)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"afa52a61-239d-44e0-89b2-0cce1b70f4a3","_uuid":"9fa97e82108699d8b9266c66b84307708ae0d638"},"cell_type":"markdown","source":"Here is a random sample of cell masks taken from the training set.  As before, each pair of images is first the image data itself and then the mask."},{"metadata":{"_cell_guid":"86658bb3-faaf-46c9-893f-d416c7b12b97","_kg_hide-input":true,"_uuid":"f161fafaa4fc755bc1ff0a374af2680104f3cd16","collapsed":true,"trusted":true},"cell_type":"code","source":"masks_shuffled = np.copy(masks)\nnp.random.shuffle(masks_shuffled)\n\nfig = plt.figure(figsize=(FIG_SIZE[1], FIG_SIZE[1]))\nouter = gridspec.GridSpec(8, 4, wspace=0.2, hspace=0.2)\n\nfor (i, mask_rec) in enumerate(itertools.islice(masks_shuffled, 32)):\n    plot_mask(fig, train_set, mask_rec, outer[i])\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"afbd22be-3f4e-4509-afb1-9d72c429be3e","_uuid":"a8334ccef60fb1c014148cc09b6546000cf4301a"},"cell_type":"markdown","source":"Here are the nuclei with the smallest and largest pixel densities in the training set.  In both cases, I think these would be impossible to predict.  It's possible they're actually labelling errors."},{"metadata":{"_cell_guid":"c0cba157-5841-416b-9e01-d815da2a4957","_kg_hide-input":true,"_uuid":"3bc2952f762fc2f8fdd32ea1074b10648c9c2d92","collapsed":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(FIG_SIZE[1], FIG_SIZE[1]))\nouter = gridspec.GridSpec(1, 2, wspace=0.2, hspace=0.2)\n\nlowest_density_mask = masks[masks.density.argmin()]\nhighest_density_mask = masks[masks.density.argmax()]\n\nplot_mask(fig, train_set, lowest_density_mask, outer[0])\nplot_mask(fig, train_set, highest_density_mask, outer[1])","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"6bec1bd1-42ed-4551-9175-4bd521128a2a","_uuid":"897242c33e59c22d7ea0d0b8abb3393c31063f63"},"cell_type":"markdown","source":"# Colors\n\nNot all images are grayscale.  Here are some statistics on color use."},{"metadata":{"_cell_guid":"c74e255b-2706-4a97-9c9a-ecfa190f192b","_kg_hide-input":true,"_kg_hide-output":false,"_uuid":"72f1dad9472c3a38b14878dbfa194e476c362cd8","collapsed":true,"trusted":true},"cell_type":"code","source":"rgba_max = np.empty((0, 4))\nrgba_min = np.empty((0, 4))\nrgba_mean = np.empty((0, 4))\nfor sample in train_set:\n    image = sample[\"image\"]\n    image = image.reshape(-1, image.shape[2])/255.0\n    rgba_max = np.concatenate((rgba_max, np.expand_dims(image.max(axis=0), 0)))\n    rgba_min = np.concatenate((rgba_min, np.expand_dims(image.min(axis=0), 0)))\n    rgba_mean = np.concatenate((rgba_mean, np.expand_dims(image.mean(axis=0), 0)))\n    #np.linalg.svd(np.cov(image.T))\n    \nrgba_max = rgba_max.max(axis=0)\nrgba_min = rgba_min.min(axis=0)\nprint(\"Maximum: \", rgba_max)\nprint(\"Minimum: \", rgba_min)\nprint(\"Mean: \", rgba_mean.mean(axis=0))\nprint(\"Alpha channel used? \", rgba_max[3] != 255 or rgba_min[3] != 255)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"522b3604-fadc-4b6f-b8a8-60ed2916431e","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"754b14cffea1a5a8e4229b57b21accf26dade493","collapsed":true,"trusted":true},"cell_type":"code","source":"from mpl_toolkits.mplot3d import Axes3D\nimport matplotlib\nsample = train_set.get(\"7f34dfccd1bc2e2466ee3d6f74ff05821a0e5404e9cf2c9568da26b59f7afda5\")\nimage = sample[\"image\"]\ncolors = np.unique(image.reshape(-1, image.shape[2]), axis=0)\ncolor_codes = np.apply_along_axis(lambda c: matplotlib.colors.rgb2hex(c / 255.0), 1, colors)\nfig = plt.figure(figsize=(20, 40))\nfig.suptitle('Color distribution')\nax = fig.add_subplot(2, 1, 1, projection='3d')\nax.view_init(30, 0)\nax.scatter(colors[..., 0] / 255.0 - 0.5, colors[..., 1] / 255.0 - 0.5, colors[..., 2] / 255.0 - 0.5, c=color_codes)\nax = fig.add_subplot(2, 1, 2, projection='3d')\nax.view_init(30, 90)\nax.scatter(colors[..., 0] / 255.0 - 0.5, colors[..., 1] / 255.0 - 0.5, colors[..., 2] / 255.0 - 0.5, c=color_codes)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"6c1ff08c-b30d-418d-bdf9-536ebb741328","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"e3f696691c343025e953bb53a58de3961be3813e","collapsed":true,"trusted":true},"cell_type":"code","source":"#sample = train_set.get(\"7f34dfccd1bc2e2466ee3d6f74ff05821a0e5404e9cf2c9568da26b59f7afda5\")\nsample = train_set.__getitem__(0)\nimage = sample[\"image\"]\npixels = image.reshape(-1, image.shape[2])/255.0\nmean = pixels.mean(axis=0)\nnp.linalg.svd(np.cov(pixels.T))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"7809f0e6-5fb9-4eee-b90a-36cee643f223","_kg_hide-input":true,"_kg_hide-output":true,"_uuid":"582601c82f40ca00056a557e25a8936e13ce8dc2","collapsed":true,"trusted":true},"cell_type":"code","source":"mask_size = np.empty((0, 2))\nfor sample in train_set:\n    for mask in sample[\"masks\"]:\n        sum = mask.sum()\n        data = [sum, sum / mask.size]\n        mask_size = np.concatenate((mask_size, np.reshape(data, (1, 2))))\nprint(\"Mask size: \")\nprint(\"Maximum: \", mask_size.max(axis=0))\nprint(\"Minimum: \", mask_size.min(axis=0))\nprint(\"Mean: \", mask_size.mean(axis=0))\nprint(\"Variance: \", mask_size.var(axis=0))","execution_count":null,"outputs":[]}],"metadata":{"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.4"}},"nbformat":4,"nbformat_minor":1}