{"cells":[{"metadata":{},"cell_type":"markdown","source":"Many thanks to the kernel [Melanoma Hair Remove](https://www.kaggle.com/vatsalparsaniya/melanoma-hair-remove). I just want to make some suggestions to this code in order to decrease the execution time.","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport time\n\nimport matplotlib.pyplot as plt\n\nimport cv2\n\npath = \"/kaggle/input/siim-isic-melanoma-classification/\"\n\ntrain_df = pd.read_csv(path + 'train.csv')\n\ntest_df = pd.read_csv(path + 'test.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The original code in [Melanoma Hair Remove](https://www.kaggle.com/vatsalparsaniya/melanoma-hair-remove) is as follows:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/vatsalparsaniya/melanoma-hair-remove\ndef hair_remove(image):\n\n    # convert image to grayScale\n    grayScale = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)\n    \n    # kernel for morphologyEx\n    kernel = cv2.getStructuringElement(1,(17,17))\n    \n    # apply MORPH_BLACKHAT to grayScale image\n    blackhat = cv2.morphologyEx(grayScale, cv2.MORPH_BLACKHAT, kernel)\n    \n    # apply thresholding to blackhat\n    _,threshold = cv2.threshold(blackhat,10,255,cv2.THRESH_BINARY)\n    \n    # inpaint with original image and threshold image\n    final_image = cv2.inpaint(image,threshold,1,cv2.INPAINT_TELEA)\n    \n    return final_image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The main part that takes the major part of the execution time is actually the \"inpaint\" method. Therefore, if we can replace this part by some similar alternatives, we can accelerate the process.\nLet's change it by some consecutive blurring steps at the hair pixels:\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def hair_remove2(image):\n    \n    grayScale = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)\n    #ax[1].imshow(grayScale)\n\n    # kernel for morphologyEx\n    kernel = cv2.getStructuringElement(1,(17,17))\n\n    # apply MORPH_BLACKHAT to grayScale image\n    blackhat = cv2.morphologyEx(grayScale, cv2.MORPH_BLACKHAT, kernel)\n    #ax[2].imshow(blackhat)\n\n    # apply thresholding to blackhat\n    _,threshold = cv2.threshold(blackhat,10,255,cv2.THRESH_BINARY)\n    #ax[3].imshow(threshold)\n    \n    im1 = image.copy()\n    im1[threshold>0] = int(255*0.7)\n    im1 = cv2.blur(im1, (10,10))\n    #ax[1].imshow(im1)\n\n    for n in range(4):\n        im2 = image.copy()\n        im2[threshold>0] = im1[threshold>0]\n        im2 = cv2.blur(im2, (10,10))\n        #ax[n+2].imshow(im2)\n        im1 = im2.copy()\n\n\n\n    final_image = image.copy()\n    final_image[threshold>0] = im2[threshold>0]\n    #ax[5].imshow(final_image)\n    \n    return final_image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's get the execution times and the final images:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"images = ['ISIC_0078712','ISIC_0080817','ISIC_0082348','ISIC_0109869','ISIC_0155012','ISIC_0159568','ISIC_0164145',\n          'ISIC_0194550','ISIC_0194914','ISIC_0202023'\n          ,'ISIC_0015719','ISIC_0074268','ISIC_0075914','ISIC_0084395','ISIC_0085718','ISIC_0081956'\n              ]\ntime1 = []\ntime2 = []\n\nfig, ax = plt.subplots(int(len(images)/2), 6, figsize=(50,50))\n\nfor i,image_name in enumerate(images):\n\n    image = cv2.imread(path + \"jpeg/train/\" + image_name + \".jpg\")\n    image = cv2.resize(image,(1024,1024))\n\n    ax[int(i/2),0+3*np.mod(i,2)].imshow(cv2.cvtColor(cv2.resize(image,(1024,1024)), cv2.COLOR_BGR2RGB))\n    ax[int(i/2),0+3*np.mod(i,2)].set_title(image_name, fontsize=30)\n\n    t1 = time.time()\n    im1 = hair_remove(image)\n    t2 = time.time()\n    tt1 = t2-t1\n    time1.append(tt1)\n    ax[int(i/2),1+3*np.mod(i,2)].imshow(cv2.cvtColor(im1, cv2.COLOR_BGR2RGB))\n    ax[int(i/2),1+3*np.mod(i,2)].set_title('inpaint ' + str(\"{:.1f}\".format(t2-t1 )) + \" sec\", fontsize=30)\n\n    image = cv2.imread(path + \"jpeg/train/\" + image_name + \".jpg\")\n    image = cv2.resize(image,(1024,1024))\n    \n    t1 = time.time()\n    im2 = hair_remove2(image)\n    t2 = time.time()\n    tt2 = t2-t1\n    time2.append(tt2)\n    ax[int(i/2),2+3*np.mod(i,2)].imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))\n    ax[int(i/2),2+3*np.mod(i,2)].set_title('blurring ' + str(\"{:.1f}\".format(t2-t1 )) + \" sec, \" + \n                      str(\"{:.1f}\".format(tt1/tt2)) + \" times faster\" , fontsize=30);\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of images: \",len(time1))\ndiff1 = np.array(time1[:-6])/np.array(time2[:-6])\nprint(\"Mean of ratio of process times for hairy images: \", diff1.mean())\nprint(\"std of ratio of process times for hairy images: \", diff1.std())\nprint(\"Number of hairy images that was processed slower: \", len(diff1[diff1<=1]))\ndiff2 = np.array(time1[-6:])/np.array(time2[-6:])\nprint(\"Mean of ratio of process times for non-hairy images: \", diff2.mean())\nprint(\"std of ratio of process times for non-hairy images: \",diff2.std())\nprint(\"Number of non-hairy images that was processed slower: \", len(diff2[diff2<=1]))\nprint(\"Time elapsed for the method with inprint: \", sum(time1))\nprint(\"Time elapsed for the method with blurring: \", sum(time2))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As we see, only in one image, the blurring method is slower than the inpaint method.\nThe total execution times:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The total execution time for these 16 images in inpaint method: \", \"{:.1f}\".format(sum(time1)), \"sec\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The total execution time for these 16 images in blurring method: \", \"{:.1f}\".format(sum(time2)), \"sec\")","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":4}