{"cells":[{"metadata":{},"cell_type":"markdown","source":"# WheatDet Augmentation Turkce Aciklamali\n\nAugmentation daha çok projelerde ezberleme (overfitting) problemini çözmek ve başarımı artırmak için kullanılır. Yapay sinir ağlarındaki temel optimizasyon algoritması olan gradient descent ( momentumlar dahil) lokal min - max'a takılabilir. Bunları aşmanın güzel bir yolu datayı artırmak ve artırırken de farklı yapılar kullanmaktır. Bu yapılar, fotoğrafı döndürmek, fotoğrafa yakınlaşmak veya uzaklaşmak, üstünden parçalar çıkarmak, üstüne parçalar ilave etmek, gürültü eklemek, değerleriyle oynamak, renk kanallarından bazılarını çıkarmak v.b olabilir. En ama en önemli nokta: projenin ilgili olduğu konuda, gerçek durumda karşılaşılabilecek örneklere göre augmentation yapmaktır. \n\nÖrneğin araba tespiti yapıyorsunuz diyelim. Arabayı vertical flip ile dikey aynalamanız güzel bir augmentationdır çünkü gerçek durumda arabalar her iki yönde de gidebilir. Lakin horizantal flip yapmak yani arabayı baş aşağı yapmak iyi bir durum olmayacaktır çünkü gerçek hayatta araçlar lastikleri üstünde giderler :)\n\nAlbumination kütüphanesi ile data augmentation ( Data artırımı )konusunu bu çalışmada inceleyeceğiz. Yararlandığımız makale aşağıdadır, okumanızı tavsiye ederim:\n\n\nAlbumentations: Fast and Flexible Image Augmentations\n\nBuslaev, A., Iglovikov, V. I., Khvedchenya, E., Parinov, A., Druzhinin, M., & Kalinin, A. A. (2020). Albumentations: Fast and Flexible Image Augmentations. Information, 11(2), 125. doi:10.3390/info11020125 \n\n> import albumentations\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport ast\nfrom collections import namedtuple\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom tqdm import tqdm\nfrom PIL import Image\n\nimport joblib\nfrom joblib import Parallel, delayed\n\nimport cv2\nimport albumentations\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom albumentations.core.transforms_interface import DualTransform\nfrom albumentations.augmentations.bbox_utils import denormalize_bbox, normalize_bbox\n\nfrom matplotlib import pyplot as plt\nimport matplotlib.patches as patches\nfrom matplotlib.image import imsave","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Aşağıdaki kütüphaneler, object detection için daha çok."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/timm-efficientdet-pytorch\")\nsys.path.insert(0, \"../input/omegaconf\")\n\nimport torch\nimport torchvision\nimport os\nfrom datetime import datetime\nimport time\nimport random\nimport cv2\nimport pandas as pd\nimport numpy as np\nimport albumentations as A\nimport matplotlib.pyplot as plt\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom sklearn.model_selection import StratifiedKFold\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch.utils.data.sampler import SequentialSampler, RandomSampler\nfrom glob import glob\n\nfrom PIL import Image\n\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2, ToTensor\n\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN\nfrom torchvision.models.detection.rpn import AnchorGenerator\n\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data.sampler import SequentialSampler\nfrom tqdm.notebook import tqdm\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\nfrom matplotlib import pyplot as plt\n\nSEED = 42\n\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Fotoğrafları görselleştiriyoruz. 6 adet random fotoğraf çağırıyoruz. "},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_folder_path = \"/kaggle/input/global-wheat-detection/train/\"\ntest_folder_path = \"/kaggle/input/global-wheat-detection/test/\"\n\ndirlist  = os.listdir(train_folder_path)\ndirtlist =  os.listdir(test_folder_path)\na=len(dirlist)\nb=len(dirtlist)\nprint(\"# of train sample: \" , a)\nprint(\"# of test sample: \" , b)\n\na=random.randint(0,a-1)\nb=random.randint(0,b-1)\nc=random.randint(0,a)\nd=random.randint(0,a)\n\nim = cv2.imread(os.path.join(train_folder_path, dirlist[a]))\nim1 = cv2.imread(os.path.join(train_folder_path, dirlist[a+b]))\nim3 = cv2.imread(os.path.join(train_folder_path, dirlist[a-b]))\nim2 = cv2.imread(os.path.join(test_folder_path, dirtlist[b]))\nim4 = cv2.imread(os.path.join(train_folder_path, dirlist[c+b]))\nim5 = cv2.imread(os.path.join(train_folder_path, dirlist[d+b]))\nim6 = cv2.imread(os.path.join(train_folder_path, dirlist[c-+b]))\n\n\nprint(\"shape of the train photo: \", im.shape)\nprint(\"shape of the test photo: \", im2.shape)\n\n\n\n\n\nfig = plt.figure()\n\n\nf, ax = plt.subplots(2,3,figsize=(20, 20)) \n\nax[0][0].imshow(im)\nax[1][0].imshow(im2)\nax[1][1].imshow(im1)\nax[0][1].imshow(im3)\nax[1][2].imshow(im5)\nax[0][2].imshow(im4)\n\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"2 tür bounding box vardır. Pascal-VOC ve COCO. Temel olarak aynı yapılardır sadece bounding box kaydedilirken farklı metrikleri saklamaktadırlar. İnternette birbirine çevrim kodları mevcuttur.\n\npascal_voc yapısı :  [x_min, y_min, x_max, y_max]\n\nCOCO yapısı :  [x_min, y_min, width, height]\n\nData frame yapısındaki bbox listesini 4 ayrı sütuna bölüyoruz. Gördüğünüz gibi xmin, ymin, width, height şeklindeki yapı bize COCO bounding box yapısına işaret ediyor.\n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Constants\nBASE_DIR = '/kaggle/input/global-wheat-detection'\nWORK_DIR = '/kaggle/working'\n\n\ntrain_df = pd.read_csv(os.path.join(BASE_DIR, 'train.csv'))\nprint(\"Initial DF shape: \", train_df.shape)\ntrain_df.head(6)\n\n# Let's expand the bounding box coordinates and calculate the area of all the bboxes\ntrain_df[['x_min','y_min', 'width', 'height']] = pd.DataFrame([ast.literal_eval(x) for x in train_df.bbox.tolist()], index= train_df.index)\ntrain_df = train_df[['image_id', 'bbox', 'source', 'x_min', 'y_min', 'width', 'height']]\ntrain_df['area'] = train_df['width'] * train_df['height']\ntrain_df['x_max'] = train_df['x_min'] + train_df['width']\ntrain_df['y_max'] = train_df['y_min'] + train_df['height']\ntrain_df = train_df.drop(['bbox', 'source'], axis=1)\ntrain_df = train_df[['image_id', 'x_min', 'y_min', 'x_max', 'y_max', 'width', 'height', 'area']]\n\n# There are some buggy annonations in training images having huge bounding boxes. Let's remove those bboxes\ntrain_df = train_df[train_df['area'] < 100000]\n\nprint(\"Final DF shape:\",train_df.shape)\ntrain_df.head(6)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Bir adet fotoğraf çağırıyoruz. BGR kanalları RGB'ye çeviriyoruz. Daha sonrasında numpy float array'e dönüştürüyoruz.\nBir başka adım ise ( her zaman gerekli değil ama daha küçük sayılarla uğraşmak için iyi bir yöntem) değerleri 255'e bölerek normalize ediyoruz. Bildiğiniz gibi RGB bir imgenin her bir renk kanalındaki pixeller 0 ile 255 arasında değer alabilir.\n\ndata frame --> np array'e çevriliyor:  \"  astype(np.int32).values \""},{"metadata":{"trusted":true},"cell_type":"code","source":"# Read the image on which data augmentaion is to be performed\n\nimage = cv2.imread(os.path.join(train_folder_path, dirlist[a]),cv2.IMREAD_COLOR)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\nimage /= 255.0\nplt.figure(figsize = (10, 10))\nplt.imshow(image)\nplt.show()\nimage_id = dirlist[a][:-4]\nprint(image_id)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Fotoğrafın üstüne bounding box'ı koyuyoruz. Çok basit bir işlem. İster pascal-voc, ister coco olsun, koordinatları alıp, fotoğrafın üstüne dikdörtgen çiziyoruz. "},{"metadata":{"trusted":true},"cell_type":"code","source":"pascal_voc_boxes = train_df[train_df['image_id'] == image_id][['x_min', 'y_min', 'x_max', 'y_max']].astype(np.int32).values\npascal_voc_boxes.shape\ncoco_boxes = train_df[train_df['image_id'] == image_id][['x_min', 'y_min', 'width', 'height']].astype(np.int32).values\ncoco_boxes.shape\nassert(len(pascal_voc_boxes) == len(coco_boxes))\nlabels = np.ones((len(pascal_voc_boxes), ))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"get_bbox fonksiyonu object detection için augmentation yaparken en önemli yapılardan birisidir. Ana fotoğrafa her nasıl augmentation uyguluyorsanız, bounding box'lar da benzer şekilde değişmelidir."},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_bbox(bboxes, col, color='white', bbox_format='pascal_voc'):\n    \n    for i in range(len(bboxes)):\n        # Create a Rectangle patch\n        if bbox_format == 'pascal_voc':\n            rect = patches.Rectangle(\n                (bboxes[i][0], bboxes[i][1]),\n                bboxes[i][2] - bboxes[i][0], \n                bboxes[i][3] - bboxes[i][1], \n                linewidth=2, \n                edgecolor=color, \n                facecolor='none')\n        else:\n            rect = patches.Rectangle(\n                (bboxes[i][0], bboxes[i][1]),\n                bboxes[i][2], \n                bboxes[i][3], \n                linewidth=2, \n                edgecolor=color, \n                facecolor='none')\n\n        # Add the patch to the Axes\n        col.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Resize, Random Crpo ve Dikey döndürme"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Random Crop & VerticalFlip\n\naug = albumentations.Compose([\n        albumentations.Resize(512, 512),   # Resize the given 1024 x 1024 image to 512 * 512\n        albumentations.VerticalFlip(1),    # Verticlly flip the image\n        albumentations.RandomCrop(height=350, width=350, p=1),\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\naug_result = aug(image=image, bboxes=pascal_voc_boxes, labels=labels)\n\nfig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 16))\nget_bbox(pascal_voc_boxes, ax[0], color='red')\nax[0].title.set_text('Original Image')\nax[0].imshow(image)\n\nget_bbox(aug_result['bboxes'], ax[1], color='red')\nax[1].title.set_text('Augmented Image')\nax[1].imshow(aug_result['image'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Gaussian Gürültü ekleme ve Cutout"},{"metadata":{"trusted":true},"cell_type":"code","source":"#GaussNoise & Cutout\n\naug = albumentations.Compose([\n        albumentations.Resize(512, 512),   # Resize the given 1024 x 1024 image to 512 * 512\n#         albumentations.VerticalFlip(1),    # Verticlly flip the image\n        albumentations.Cutout(num_holes=8, max_h_size=26, max_w_size=56, fill_value=0, p=1),\n        albumentations.GaussNoise(var_limit=(0.002, 0.002), p=1),\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\n\naug_result = aug(image=image, bboxes=pascal_voc_boxes, labels=labels)\nfig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 16))\n\nget_bbox(pascal_voc_boxes, ax[0], color='red')\nax[0].title.set_text('Original Image')\nax[0].imshow(image)\n\nget_bbox(aug_result['bboxes'], ax[1], color='red')\nax[1].title.set_text('Augmented Image')\nax[1].imshow(aug_result['image'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Kar Yağdırma"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Random Snow\naug = albumentations.Compose([\n        albumentations.Resize(512, 512),   # Resize the given 1024 x 1024 image to 512 * 512\n#         albumentations.VerticalFlip(1),    # Verticlly flip the image\n        albumentations.RandomSnow(p=1),\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\naug_result = aug(image=image, bboxes=pascal_voc_boxes, labels=labels)\nfig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 16))\nget_bbox(pascal_voc_boxes, ax[0], color='red')\nax[0].title.set_text('Original Image')\nax[0].imshow(image)\n\nget_bbox(aug_result['bboxes'], ax[1], color='red')\nax[1].title.set_text('Augmented Image')\nax[1].imshow(aug_result['image'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Yağmur yağdırma"},{"metadata":{"trusted":true},"cell_type":"code","source":"#RandomRain\naug = albumentations.Compose([\n        albumentations.Resize(512, 512),   # Resize the given 1024 x 1024 image to 512 * 512\n#         albumentations.VerticalFlip(1),    # Verticlly flip the image\n        albumentations.RandomRain(p=1),\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\naug_result = aug(image=image, bboxes=pascal_voc_boxes, labels=labels)\nfig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 16))\nget_bbox(pascal_voc_boxes, ax[0], color='red')\nax[0].title.set_text('Original Image')\nax[0].imshow(image)\n\nget_bbox(aug_result['bboxes'], ax[1], color='red')\nax[1].title.set_text('Augmented Image')\nax[1].imshow(aug_result['image'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Güneş Yansıması Ekleme"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Random Sun Flake\naug = albumentations.Compose([\n        albumentations.Resize(512, 512),   # Resize the given 1024 x 1024 image to 512 * 512\n#         albumentations.VerticalFlip(1),    # Verticlly flip the image\n        albumentations.RandomSunFlare(flare_roi=(0, 0, 1, 0.4), src_radius=100, src_color=(255, 255, 255), p=1),\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\naug_result = aug(image=image, bboxes=pascal_voc_boxes, labels=labels)\nfig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 16))\nget_bbox(pascal_voc_boxes, ax[0], color='red')\nax[0].title.set_text('Original Image')\nax[0].imshow(image)\n\nget_bbox(aug_result['bboxes'], ax[1], color='red')\nax[1].title.set_text('Augmented Image')\nax[1].imshow(aug_result['image'])\nplt.show()","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}