{"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 matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport math\nfrom sklearn import mixture\nfrom sklearn.utils import shuffle\nfrom skimage import measure\nfrom glob import glob\nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-06-13T16:07:56.112285Z","iopub.execute_input":"2022-06-13T16:07:56.114093Z","iopub.status.idle":"2022-06-13T16:07:57.240759Z","shell.execute_reply.started":"2022-06-13T16:07:56.112638Z","shell.execute_reply":"2022-06-13T16:07:57.239802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_DATA = \"../input/intel-mobileodt-cervical-cancer-screening/train/train\"\nTEST_DATA = \"../input/intel-mobileodt-cervical-cancer-screening/test/test\"\n\ntrain_files = glob(os.path.join(TRAIN_DATA, \"*\", \"*.jpg\"))\ntest_files = glob(os.path.join(TEST_DATA, \"*.jpg\"))","metadata":{"execution":{"iopub.status.busy":"2022-06-13T16:07:57.242504Z","iopub.execute_input":"2022-06-13T16:07:57.242833Z","iopub.status.idle":"2022-06-13T16:07:57.840624Z","shell.execute_reply.started":"2022-06-13T16:07:57.242804Z","shell.execute_reply":"2022-06-13T16:07:57.839753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_image_data(fname):\n    img = cv2.imread(fname)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    return img\n\n\ndef maxHist(hist):\n    maxArea = (0, 0, 0)\n    height = []\n    position = []\n    for i in range(len(hist)):\n        if (len(height) == 0):\n            if (hist[i] > 0):\n                height.append(hist[i])\n                position.append(i)\n        else:\n            if (hist[i] > height[-1]):\n                height.append(hist[i])\n                position.append(i)\n            elif (hist[i] < height[-1]):\n                while (height[-1] > hist[i]):\n                    maxHeight = height.pop()\n                    area = maxHeight * (i - position[-1])\n                    if (area > maxArea[0]):\n                        maxArea = (area, position[-1], i)\n                    last_position = position.pop()\n                    if (len(height) == 0):\n                        break\n                position.append(last_position)\n                if (len(height) == 0):\n                    height.append(hist[i])\n                elif (height[-1] < hist[i]):\n                    height.append(hist[i])\n                else:\n                    position.pop()\n    while (len(height) > 0):\n        maxHeight = height.pop()\n        last_position = position.pop()\n        area = maxHeight * (len(hist) - last_position)\n        if (area > maxArea[0]):\n            maxArea = (area, len(hist), last_position)\n    return maxArea\n\n\ndef maxRect(img):\n    maxArea = (0, 0, 0)\n    addMat = np.zeros(img.shape)\n    for r in range(img.shape[0]):\n        if r == 0:\n            addMat[r] = img[r]\n            area = maxHist(addMat[r])\n            if area[0] > maxArea[0]:\n                maxArea = area + (r,)\n        else:\n            addMat[r] = img[r] + addMat[r - 1]\n            addMat[r][img[r] == 0] *= 0\n            area = maxHist(addMat[r])\n            if area[0] > maxArea[0]:\n                maxArea = area + (r,)\n    return (\n    int(maxArea[3] + 1 - maxArea[0] / abs(maxArea[1] - maxArea[2])), maxArea[2], maxArea[3], maxArea[1], maxArea[0])\n","metadata":{"execution":{"iopub.status.busy":"2022-06-13T16:07:57.841764Z","iopub.execute_input":"2022-06-13T16:07:57.8422Z","iopub.status.idle":"2022-06-13T16:07:57.860801Z","shell.execute_reply.started":"2022-06-13T16:07:57.842171Z","shell.execute_reply":"2022-06-13T16:07:57.859399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cropCircle(img):\n    if (img.shape[0] > img.shape[1]):\n        tile_size = (int(img.shape[1] * 256 / img.shape[0]), 256)\n    else:\n        tile_size = (256, int(img.shape[0] * 256 / img.shape[1]))\n\n    img = cv2.resize(img, dsize=tile_size)\n\n    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n    _, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)\n\n    contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n\n    main_contour = sorted(contours, key=cv2.contourArea, reverse=True)[0]\n\n    ff = np.zeros((gray.shape[0], gray.shape[1]), 'uint8')\n    cv2.drawContours(ff, main_contour, -1, 1, 15)\n    ff_mask = np.zeros((gray.shape[0] + 2, gray.shape[1] + 2), 'uint8')\n    cv2.floodFill(ff, ff_mask, (int(gray.shape[1] / 2), int(gray.shape[0] / 2)), 1)\n    # cv2.circle(ff, (int(gray.shape[1]/2), int(gray.shape[0]/2)), 3, 3, -1)\n\n    rect = maxRect(ff)\n    img_crop = img[min(rect[0], rect[2]):max(rect[0], rect[2]), min(rect[1], rect[3]):max(rect[1], rect[3])]\n    cv2.rectangle(ff, (min(rect[1], rect[3]), min(rect[0], rect[2])), (max(rect[1], rect[3]), max(rect[0], rect[2])), 3,\n                  2)\n\n    return img_crop\n\ndef Ra_space(img, Ra_ratio, a_threshold):\n    imgLab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)\n    w = img.shape[0]\n    h = img.shape[1]\n    Ra = np.zeros((w * h, 2))\n    for i in range(w):\n        for j in range(h):\n            R = math.sqrt((w / 2 - i) * (w / 2 - i) + (h / 2 - j) * (h / 2 - j))\n            Ra[i * h + j, 0] = R\n            Ra[i * h + j, 1] = min(imgLab[i][j][1], a_threshold)\n\n    Ra[:, 0] /= max(Ra[:, 0])\n    Ra[:, 0] *= Ra_ratio\n    Ra[:, 1] /= max(Ra[:, 1])\n\n    return Ra","metadata":{"execution":{"iopub.status.busy":"2022-06-13T16:07:57.862961Z","iopub.execute_input":"2022-06-13T16:07:57.863384Z","iopub.status.idle":"2022-06-13T16:07:57.882516Z","shell.execute_reply.started":"2022-06-13T16:07:57.86335Z","shell.execute_reply":"2022-06-13T16:07:57.881472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def img_is_color(img):\n\n    if len(img.shape) == 3:\n        # Check the color channels to see if they're all the same.\n        c1, c2, c3 = img[:, : , 0], img[:, :, 1], img[:, :, 2]\n        if (c1 == c2).all() and (c2 == c3).all():\n            return True\n\n    return False\n\ndef show_image_list(list_images, list_titles=None, list_cmaps=None, grid=True, num_cols=2, figsize=(20, 10), title_fontsize=30):\n    '''\n    Shows a grid of images, where each image is a Numpy array. The images can be either\n    RGB or grayscale.\n\n    Parameters:\n    ----------\n    images: list\n        List of the images to be displayed.\n    list_titles: list or None\n        Optional list of titles to be shown for each image.\n    list_cmaps: list or None\n        Optional list of cmap values for each image. If None, then cmap will be\n        automatically inferred.\n    grid: boolean\n        If True, show a grid over each image\n    num_cols: int\n        Number of columns to show.\n    figsize: tuple of width, height\n        Value to be passed to pyplot.figure()\n    title_fontsize: int\n        Value to be passed to set_title().\n    '''\n\n    assert isinstance(list_images, list)\n    assert len(list_images) > 0\n    assert isinstance(list_images[0], np.ndarray)\n\n    if list_titles is not None:\n        assert isinstance(list_titles, list)\n        assert len(list_images) == len(list_titles), '%d imgs != %d titles' % (len(list_images), len(list_titles))\n\n    if list_cmaps is not None:\n        assert isinstance(list_cmaps, list)\n        assert len(list_images) == len(list_cmaps), '%d imgs != %d cmaps' % (len(list_images), len(list_cmaps))\n\n    num_images  = len(list_images)\n    num_cols    = min(num_images, num_cols)\n    num_rows    = int(num_images / num_cols) + (1 if num_images % num_cols != 0 else 0)\n\n    # Create a grid of subplots.\n    fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize)\n    \n    # Create list of axes for easy iteration.\n    if isinstance(axes, np.ndarray):\n        list_axes = list(axes.flat)\n    else:\n        list_axes = [axes]\n\n    for i in range(num_images):\n\n        img    = list_images[i]\n        title  = list_titles[i] if list_titles is not None else 'Image %d' % (i)\n        cmap   = list_cmaps[i] if list_cmaps is not None else (None if img_is_color(img) else 'gray')\n        \n        list_axes[i].imshow(img, cmap=cmap)\n        list_axes[i].set_title(title, fontsize=title_fontsize) \n        list_axes[i].grid(grid)\n\n    for i in range(num_images, len(list_axes)):\n        list_axes[i].set_visible(False)\n\n    fig.tight_layout()\n    _ = plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-06-13T16:07:57.883771Z","iopub.execute_input":"2022-06-13T16:07:57.884297Z","iopub.status.idle":"2022-06-13T16:07:57.901903Z","shell.execute_reply.started":"2022-06-13T16:07:57.884263Z","shell.execute_reply":"2022-06-13T16:07:57.901162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for f in sorted(train_files)[:5]:\n    if TRAIN_DATA in f:\n        img_type = 'train'\n        clss = int(os.path.basename(os.path.dirname(f)).split('_')[1]) - 1\n        print(f,clss)\n    if TEST_DATA in f:\n        img_type = 'test'\n        clss = int(os.path.basename(os.path.dirname(f)).split('_')[1]) - 1\n        print(f,clss)\n    try:\n        img = get_image_data(f)\n    except:\n        print('Image read error: {}. Skip it!'.format(f))\n        continue\n    if img is None:\n        print('Problem with image: {}. Skip it!'.format(f))\n        continue\n    initial_shape = img.shape[:2]\n\n    img = cropCircle(img)\n    w = img.shape[0]\n    h = img.shape[1]\n\n    imgLab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)\n    Ra = Ra_space(img, 1.0, 150)\n    a_channel = np.reshape(Ra[:, 1], (w, h))\n    g = mixture.GaussianMixture(n_components=2, covariance_type='diag', random_state=0, init_params='kmeans')\n    image_array_sample = shuffle(Ra, random_state=0)[:1000]\n    g.fit(image_array_sample)\n    labels = g.predict(Ra)\n    labels += 1  \n    labels_2D = np.reshape(labels, (w, h))\n    gg_labels_regions = measure.regionprops(labels_2D, intensity_image=a_channel)\n    gg_intensity = [prop.mean_intensity for prop in gg_labels_regions]\n    cervix_cluster = gg_intensity.index(max(gg_intensity)) + 1\n    mask = np.zeros((w * h, 1), 'uint8')\n    mask[labels == cervix_cluster] = 255\n    mask_2D = np.reshape(mask, (w, h))\n    cc_labels = measure.label(mask_2D, background=0)\n    regions = measure.regionprops(cc_labels)\n    areas = [prop.area for prop in regions]\n    regions_label = [prop.label for prop in regions]\n    largestCC_label = regions_label[areas.index(max(areas))]\n    mask_largestCC = np.zeros((w, h), 'uint8')\n    mask_largestCC[cc_labels == largestCC_label] = 255\n    img_masked = img.copy()\n    img_masked[mask_largestCC == 0] = (0, 0, 0)\n    img_masked_gray = cv2.cvtColor(img_masked, cv2.COLOR_RGB2GRAY)\n    _, thresh_mask = cv2.threshold(img_masked_gray, 0, 255, 0)\n    kernel = np.ones((11, 11), np.uint8)\n    thresh_mask = cv2.dilate(thresh_mask, kernel, iterations=1)\n    thresh_mask = cv2.erode(thresh_mask, kernel, iterations=2)\n    contours_mask,_ = cv2.findContours(thresh_mask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n\n    try:\n        main_contour = sorted(contours_mask, key=cv2.contourArea, reverse=True)[0]\n    except:\n        print('Contour problem for {}. skip it!'.format(f))\n        continue\n\n    x, y, w, h = cv2.boundingRect(main_contour)\n    crop_img = img[y:y+h, x:x+w]\n    crop_img = cv2.resize(crop_img, (256, 256))\n    show_image_list(list_images=[img,crop_img], \n                list_titles=['original', 'cropped'],\n                num_cols=2,\n                figsize=(20, 10),\n                grid=False,\n                title_fontsize=20)\n    print('Image shape is : ',crop_img.shape)\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2022-06-13T16:07:57.903276Z","iopub.execute_input":"2022-06-13T16:07:57.90369Z","iopub.status.idle":"2022-06-13T16:08:05.604275Z","shell.execute_reply.started":"2022-06-13T16:07:57.903661Z","shell.execute_reply":"2022-06-13T16:08:05.603455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}