{"cells":[{"metadata":{"_uuid":"2333630bd0e91a2d3fab97bd8884de9d2e45d2ff"},"cell_type":"markdown","source":"# ==> FOREWORD"},{"metadata":{"_uuid":"25709136f05917983dfc84d80918c5a9eee7fcfd"},"cell_type":"markdown","source":"The task is to dentify the cells’ nuclei. Identifying nuclei allows researchers to identify each individual cell in a sample, and by measuring how cells react to various treatments, the researcher can understand the underlying biological processes at work.\nAnd the target is automate the process of identifying nuclei, we have 670 cases for train and 65 cases for test at first stage.\n"},{"metadata":{"_uuid":"155a54bad5416d5f71e9fc848ffdf6bd3ebd2247"},"cell_type":"markdown","source":"This is a very interesting and useful topic, and I have applied U-NET or pure computer vision techniques based on kernel as follows:\n https://www.kaggle.com/keegil/keras-u-net-starter-lb-0-277\n https://www.kaggle.com/gaborvecsei/basic-pure-computer-vision-segmentation-lb-0-229\nBoth results are very good for train dataset (iou was around 0.80),but wasn't so good on test dataset\nAfter have a view of all these pictures, we should notice that actually there are different types of image and a pre-classification should work when we use U-NET model,which means to divide the train and test dataset into different subset,and then use Neutral Network to train and predict seperately."},{"metadata":{"_uuid":"1b9ea3c3e192ca70554fc28d1246c1179ec6b1a5"},"cell_type":"markdown","source":"And this kernel is just one attempt to complete classification, I believe there exists better solutions and hope someone can improve my kernel. "},{"metadata":{"_uuid":"0bd434b194962360e2acf33e3b5e6b428d4395af"},"cell_type":"markdown","source":"# ==> Step1: get images and extrac useful information"},{"metadata":{"trusted":false,"_uuid":"dcb2ea3e4b248b73483839164bc64c8fce95a7bf"},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom skimage.io import imread, imshow, imread_collection, concatenate_images\nimport os\nfrom os.path import join\nimport glob\nimport cv2\n%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom skimage.transform import resize\n\nTRAIN_PATH = '../input/stage1_train/'\nTEST_PATH = '../input/stage1_test/'\nIMG_WIDTH = 32\nIMG_HEIGHT = 32\nIMG_CHANNELS = 3\n\ntrain_ids = os.listdir(TRAIN_PATH)\ntest_ids = os.listdir(TEST_PATH)\n\ntrain_image_paths = [glob.glob(join(TRAIN_PATH, train_id, \"images\", \"*\"))[0] for train_id in train_ids]\ntest_image_paths = [glob.glob(join(TEST_PATH, test_id, \"images\", \"*\"))[0] for test_id in test_ids]\n\nfrom tqdm import tqdm\n\n\ndef get_image_finfo(image_paths):\n    # complete img ,rgb mode\n    full_img_list = []\n    # just grey mode\n    img_list = []\n    \n    # average value of gray pixels per image\n    average_list = []\n    \n    # max Contour area value per image\n    max_cnt_area = []\n    \n    # mean Contour area value per image\n    average_cnt_area = []\n    \n    # how many Contour areas per image\n    num_cnt = []\n    \n    #  width per image\n    wid_list = []\n    \n    #  length per image\n    len_list = []\n    \n    #  red per image\n    r=[]\n    \n    #  green\n    g=[]\n    \n    #  blue\n    b=[]\n    for case in tqdm(image_paths, total=len(image_paths)): \n        img = imread(case)[:,:,:IMG_CHANNELS]\n        full_img_list.append(img)  \n        r.append(np.average(img[:,:,0]))\n        g.append(np.average(img[:,:,1]))\n        b.append(np.average(img[:,:,2]))\n        \n        img = cv2.imread(case,cv2.IMREAD_GRAYSCALE)\n        \n        # in some cases, image background is bright and cell darker, there needs a inverse of pixel value\n        if np.average(img) > 125:\n            img = 255 - img   \n        img_list.append(img)\n\n        lenth = img.shape[0]\n        len_list.append(lenth)\n        width = img.shape[1]\n        wid_list.append(width)\n        average_list.append(np.average(img))\n        \n        # use opencv to find contour and get some stactistic data\n        img = cv2.GaussianBlur(img, (3, 3), 1)\n        ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)\n\n        _, cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n        cnts = sorted(cnts, key=cv2.contourArea, reverse=True)\n        max_cnt_area.append(cv2.contourArea(cnts[0])/lenth/width)\n\n        av = 0\n        for i in cnts:\n            av = av + cv2.contourArea(i)\n        av = av/len(cnts)\n        \n        # since different pic has different size, we'd better normalise it \n        average_cnt_area.append(av/lenth/width)\n        num_cnt.append(len(cnts))\n        \n    df = pd.DataFrame({'img':full_img_list,'max_area':max_cnt_area,'average_area':average_cnt_area,\n                       'num_cnt':num_cnt,'average':average_list,'wid':wid_list,'len':len_list,\n                       'r':r,'g':g,'b':b\n                      }) \n    return df","execution_count":92,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"97bb91483f3de6bef676481305d45f6a2b2a7e5c"},"cell_type":"code","source":"df = get_image_finfo(train_image_paths)","execution_count":93,"outputs":[]},{"metadata":{"_uuid":"67aaaa9f8693b7659b80780a3205f388063e7c52"},"cell_type":"markdown","source":"# ==> Step2: apply K-means solution to classify train images"},{"metadata":{"_uuid":"e29bb6c84e52efac0d359c7e4ad7b055098a4744"},"cell_type":"markdown","source":"since we have no correct class labels of each image , an unsupervised solution model K-means was an appropriate method, at least for me. "},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"c3a8bb1b27c018f5bf2a111563ee41486b8a72e3"},"cell_type":"code","source":"# divide into 3 categories according to characters belong to form\nFDIV = 3\n# divide into 3 categories according to characters belong to color\nCDIV = 3","execution_count":124,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"cf0ffd18597446a4a65a1ca641f62efcc8bddc86"},"cell_type":"code","source":"from sklearn.cluster import KMeans \n\n# train seperately\ninput_x = np.array(df[['max_area','average_area','num_cnt','average','wid','len']])\n  \nfkmeans = KMeans(n_clusters = FDIV).fit(input_x) \n\ndf['flabel'] = fkmeans.labels_\n\ninput_c = np.array(df[['r','g','b']])\n  \nckmeans = KMeans(n_clusters = CDIV).fit(input_c) \n\ndf['clabel'] = ckmeans.labels_\n\n# and then make an combination\ndf['cflabel'] = FDIV *df['flabel']\n\ndf['cflabel'] = df['cflabel'] + df['clabel']\n\ndf['cflabel'].hist()","execution_count":127,"outputs":[]},{"metadata":{"_uuid":"8f1fc7be9c9839cec1c0dd38dc98217ecfc41b17"},"cell_type":"markdown","source":"most images belong to one type(value differ after each train) , and we draw images according to different types to see if these images are seperated well\nwe can find that most images in one type are similar with each other, but there alsoexists some errors like type6(value differ after each train)."},{"metadata":{"trusted":false,"_uuid":"6d55910614b58e6a28d348e66022a7cb0c3e9f07"},"cell_type":"code","source":"for t in range(FDIV*CDIV):\n    print('for type=>'+str(t))\n    fig,ax= plt.subplots(2,10,figsize=(32,5))\n    \n    n=0\n    for i in range(2):\n        for j in range(10):\n            if n < len(df[df['cflabel']==t].index):\n                sn = df[df['cflabel']==t].index[n]\n                ax[i,j].imshow(df.img[sn])\n                n = n+1\n    plt.show()\n","execution_count":130,"outputs":[]},{"metadata":{"_uuid":"ecece0d9dfda8af11e0276245fdd74b170fbba37"},"cell_type":"markdown","source":"# ==> Step3: apply fited K-means model to classify test images"},{"metadata":{"trusted":false,"_uuid":"59ed6baeec926cc5e8d7acbbd87ad08008d76da4"},"cell_type":"code","source":"test_df = get_image_finfo(test_image_paths)\n","execution_count":121,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"2301a6d086f568ae4411c4fdf733845a4bac20b2"},"cell_type":"code","source":"input_x = np.array(test_df[['max_area','average_area','num_cnt','average','wid','len']])\n  \ntest_df['flabel'] = fkmeans.predict(input_x)\n\ninput_c = np.array(test_df[['r','g','b']])\n  \ntest_df['clabel'] = ckmeans.predict(input_c)\n\ntest_df['cflabel'] = FDIV *test_df['flabel']\n\ntest_df['cflabel'] = test_df['cflabel'] + test_df['clabel']\n\ntest_df['cflabel'].hist()","execution_count":128,"outputs":[]},{"metadata":{"_uuid":"ccb027523b9c1d7b37e361b8be30c051b5b4f89b"},"cell_type":"markdown","source":"we have to notice that some type of images are not found in train datasets, which means this type of image is completely new for the SOLUTION MODEL and hard to predict."},{"metadata":{"trusted":false,"_uuid":"5483fede50e5688c7e3227cb47b2388ca120317a"},"cell_type":"code","source":"for t in range(FDIV*CDIV):\n    print('for type=>'+str(t))\n    \n    fig,ax= plt.subplots(2,10,figsize=(32,5))\n    n=0\n    for i in range(2):\n        for j in range(10):\n            if n < len(test_df[test_df['cflabel']==t].index):\n                sn = test_df[test_df['cflabel']==t].index[n]\n                ax[i,j].imshow(test_df.img[sn])\n                n = n+1\n    plt.show()","execution_count":129,"outputs":[]},{"metadata":{"_uuid":"0ba671d763568da40dbaf16ef68892d861e7fd8c"},"cell_type":"markdown","source":"# Conclusion"},{"metadata":{"_uuid":"9a15e67f7b470e8721de9c909eba187ead09d757"},"cell_type":"markdown","source":"finaly just a complete view of test images, My suggestion is each type of test images need a U-NET model trained by same type train images to predict, and I will continue to research on this direction and check if it's a good solution, I will \nupdate this kernel continuely\nhope you can join with me and give me advices.\n\n\n(1) divide train and test dataset into different category\n(2) train and predict U-NET model with train images and test images of same type\n\nNotice:\nThere still are some mixture images under one type\nwe need to find some new characters or a better solution model to clasify images \n"},{"metadata":{"trusted":false,"_uuid":"256b5e1bbc6ed10cfc1dbe7cedc55705faff57ba"},"cell_type":"code","source":"\nfig,ax= plt.subplots(10,10,figsize=(32,32))\nn=0\nfor i in range(10):\n    for j in range(10):\n        if n < len(test_df.index):\n            \n            ax[i,j].imshow(test_df.img[n])\n            n = n+1\nplt.show()","execution_count":100,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"87cdae4b3ec0c42f6df9cf5d4cd486471176e8f3"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":2},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython2","version":"2.7.13"}},"nbformat":4,"nbformat_minor":1}