{"cells":[{"metadata":{},"cell_type":"markdown","source":"Generate new images using CutMix(A beginner guide for other beginners)"},{"metadata":{},"cell_type":"markdown","source":"Import needed packages"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport random\nimport numpy as np \nimport pandas as pd \nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\nimport tensorflow as tf\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Original paper : https://arxiv.org/pdf/1905.04899.pdf\n\nCutMix augmentation strategy: patches are cut and pasted among training images where the ground truth labels are also mixed proportionally to the area of the patches. "},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_images(imgPath1,imgPath2,label1, label2, crop_size=256):\n       \n    img1 = Image.open(imgPath1)\n    img1 = np.array(img1)\n    img1_height, img1_width = img1.shape[:-1]\n    \n    img2 = Image.open(imgPath2)\n    img2 = np.array(img2)\n    img2_height, img2_width = img2.shape[:-1]\n    \n    \n    x1 = random.randint(0,img1_height-crop_size)\n    y1 = random.randint(0,img1_width-crop_size)\n    \n\n    x2 = random.randint(0,img2_height-crop_size)\n    y2 = random.randint(0,img2_width-crop_size)\n    \n\n    cropped1 = img1.copy()[x1:x1+crop_size , y1:y1+crop_size,:]\n    \n    cropped2 = img2.copy()[x2:x2+crop_size , y2:y2+crop_size,:]\n        \n        \n    img1[x1:x1+crop_size , y1:y1+crop_size,:] = cropped2\n    img2[x2:x2+crop_size , y2:y2+crop_size,:] = cropped1\n    \n    alpha1 = (crop_size * crop_size) / (img1_height * img1_width)\n    beta1 = 1 - alpha1\n    \n    alpha2 = (crop_size * crop_size) / (img2_height * img2_width)\n    beta2 = 1 - alpha2\n    \n    newlabel1 = beta1 * label1 + alpha1 * label2\n    \n    newlabel2 = alpha2 * label1 + beta2 * label2\n    \n    return  img1, img2, newlabel1, newlabel2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imgpath1 = \"../input/cassava-leaf-disease-classification/train_images/1000015157.jpg\"\nimgpath2 = \"../input/cassava-leaf-disease-classification/train_images/1002394761.jpg\"\n\n#these labels are just some example, they doesn't reflect these images\nl1 = np.array([0, 0, 0, 0, 1])\nl2 = np.array([0, 0, 0, 1, 0])\n\nimg1, img2, l1, l2 = generate_images(imgpath1, imgpath2,l1, l2)\n\nplt.figure(figsize = (20, 20))\nplt.subplot(2, 1, 1)\nplt.imshow(img1)\n\nplt.subplot(2, 1, 2)\nplt.imshow(img2)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"New labels are: \")\nprint(l1, l2, sep = \"\\n\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"***Or we can apply Cutout to images***"},{"metadata":{"trusted":true},"cell_type":"code","source":"def cutout(imagePath, num_holes, hole_size, rescale_to = 512):\n    \n    img = Image.open(imgPath)\n    img = np.array(img)\n    img_height, img_width = img.shape[:-1]\n    \n    for i in range(num_holes):    \n        x = random.randint(0,img_height-hole_size)\n        y = random.randint(0,img_width-hole_size)\n        img[x:x+hole_size , y:y+hole_size,:] = 0\n        \n    #random crop a patch of rescale_to x rescale_to    \n    x = random.randint(0,img_height-rescale_to)\n    y = random.randint(0,img_width-rescale_to)\n    return  img[x:x+rescale_to , y:y+rescale_to,:]\n    \n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imgPath = \"../input/cassava-leaf-disease-classification/train_images/1000015157.jpg\"\ncutoutImg = cutout(imgPath, 30, 20)\nplt.imshow(cutoutImg)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cutoutImg = cutout(imgPath, 5 , 80)\nplt.imshow(cutoutImg)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGES = \"../input/cassava-leaf-disease-classification/train_images/\"\n\ndf = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")\ndf['path'] = IMAGES + df['image_id']\n\ndf = df.sample(frac = 1) \ndf.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Get the labels**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = tf.keras.utils.to_categorical(df['label'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Make a new directory, to save images in it"},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir CutMixImages","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's generate some data"},{"metadata":{"trusted":true},"cell_type":"code","source":"newlabels = []\nnewpaths  = []\nid = 0\n\n# generate just 10 images in this case\nfor i in range(0, 10, 2):\n    \n    l1 = labels[i]\n    l2 = labels[i+1]\n    \n    img1, img2, l1, l2 = generate_images(df['path'][i],df['path'][i+1],l1, l2)\n\n    id += 1 \n    img1 = Image.fromarray(np.uint8(img1)).convert('RGB')\n    img1.save(\"./CutMixImages/image\"+str(id)+\".jpg\")\n    newpaths.append(\"image\"+str(id)+\".jpg\")  \n    \n    id += 1\n    img2 = Image.fromarray(np.uint8(img2)).convert('RGB')\n    img2.save(\"./CutMixImages/image\"+str(id)+\".jpg\")\n    newpaths.append(\"image\"+str(id)+\".jpg\")  \n    \n    newlabels.append(l1)\n    newlabels.append(l2)    \n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Visualize the new generated images**"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (20, 20))\nimage = Image.open(\"./CutMixImages/image2.jpg\")\nplt.subplot(2, 1, 1)\nplt.imshow(image)\n\nimage = Image.open(\"./CutMixImages/image1.jpg\")\nplt.subplot(2, 1, 2)\nplt.imshow(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"generated_data = pd.DataFrame(columns = [\"path\", \"l1\", \"l2\", \"l3\", \"l4\", \"l5\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"generated_data['path'] = newpaths\ngenerated_data['l1'] = [label[0] for label in newlabels]\ngenerated_data['l2'] = [label[1] for label in newlabels]\ngenerated_data['l3'] = [label[2] for label in newlabels]\ngenerated_data['l4'] = [label[3] for label in newlabels]\ngenerated_data['l5'] = [label[4] for label in newlabels]\n\ngenerated_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import shutil\nshutil.make_archive(\"CutMixImages\", 'zip', \"/kaggle/working/CutMixImages/\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Download the zip archive and the csv "},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import FileLink\nFileLink('./CutMixImages.zip')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"generated_data.to_csv(\"newdata.csv\", index=False)","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}