{"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 numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport os\nimport random\nimport cv2\n\nimport warnings\nwarnings.simplefilter(action='ignore', category=FutureWarning)","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:19:19.867765Z","iopub.execute_input":"2021-11-22T22:19:19.868034Z","iopub.status.idle":"2021-11-22T22:19:20.104156Z","shell.execute_reply.started":"2021-11-22T22:19:19.868007Z","shell.execute_reply":"2021-11-22T22:19:20.103302Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-family:verdana;\"><h1 style=\"font-size:200%; padding: 10px; background: #4169E1;\"><b style=\"color:white;\">Control Crown-of-Thorns Starfish</b></h1></center>\n\n\nCrown-of-Thorns Starfish\n\n\"Since 1962, crown-of-thorns starfish outbreaks have had a major impact on the many reefs that make up the Great Barrier Reef. A fourth outbreak is currently underway in the World-Heritage Area.\"\n\n\"Crown-of-thorns starfish (also known as COTS) are marine invertebrates that feed on coral. They occur naturally on reefs throughout the Indo-Pacific region, and when conditions are right, they can reach plague proportions and devastate hard coral communities.\"\n\n\"Laboratory research at AIMS (Australian Institute of Marine Science) has shown that survival of crown-of-thorns starfish larvae increases dramatically when phytoplankton, their food source, becomes more abundant. Phytoplankton numbers are usually low in reef waters, but production can increase rapidly if early-season monsoonal and cyclonic floods carry fertilisers and other pollutants into the Great Barrier Reef lagoon.\"\n\n\"Once dense breeding populations of starfish develop on some reefs, the huge numbers of larvae that they produce can establish outbreaks on mid-shelf reefs in the central Reef, even though these reefs are hardly ever affected by runoff.\"\n\nhttps://www.aims.gov.au/docs/research/biodiversity-ecology/threats/cots.html","metadata":{}},{"cell_type":"markdown","source":"#Surviving corals eaten by Crown of Thorns Starfish | WWF-Australia\n\nhttps://www.youtube.com/watch?v=c9-QGMUUbbU  - 10 de jan. de 2019\n\nScientists fear starfish could combine with bleaching in “perfect storm” of Reef destruction. \n\nA new WWF-Australia report urges a crackdown on the “excessive, and often illegal,” use of industrial fertilisers that trigger outbreaks.\n–\n\nMORE FROM WWF-AUSTRALIA\n\nSOCIAL:\nFacebook... ►https://www.facebook.com/wwfaustralia/\nInstagram.. ► https://www.instagram.com/wwf_australia/\nTwitter........ ► https://twitter.com/WWF_Australia/","metadata":{}},{"cell_type":"markdown","source":"<iframe width=\"956\" height=\"538\" src=\"https://www.youtube.com/embed/c9-QGMUUbbU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>","metadata":{}},{"cell_type":"code","source":"os.listdir('../input/tensorflow-great-barrier-reef/')","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:09:44.567429Z","iopub.execute_input":"2021-11-22T22:09:44.568222Z","iopub.status.idle":"2021-11-22T22:09:44.578050Z","shell.execute_reply.started":"2021-11-22T22:09:44.568180Z","shell.execute_reply":"2021-11-22T22:09:44.577165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv', index_col=0)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:11:24.310766Z","iopub.execute_input":"2021-11-22T22:11:24.311075Z","iopub.status.idle":"2021-11-22T22:11:24.387950Z","shell.execute_reply.started":"2021-11-22T22:11:24.311039Z","shell.execute_reply":"2021-11-22T22:11:24.387156Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv('../input/tensorflow-great-barrier-reef/test.csv', index_col=0)\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:12:20.158995Z","iopub.execute_input":"2021-11-22T22:12:20.159304Z","iopub.status.idle":"2021-11-22T22:12:20.177292Z","shell.execute_reply.started":"2021-11-22T22:12:20.159274Z","shell.execute_reply":"2021-11-22T22:12:20.176326Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://www.gbrmpa.gov.au/__data/assets/image/0010/267229/varieties/max1300.jpg)gbrmpa.gov.au","metadata":{}},{"cell_type":"code","source":"!pip install kornia","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:21:13.893168Z","iopub.execute_input":"2021-11-22T22:21:13.894211Z","iopub.status.idle":"2021-11-22T22:21:23.204203Z","shell.execute_reply.started":"2021-11-22T22:21:13.894148Z","shell.execute_reply":"2021-11-22T22:21:23.203171Z"},"_kg_hide-input":false,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#It's a TensorFlow Competition.  My bad, I'm sorry.","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nimport kornia as K","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:21:36.029551Z","iopub.execute_input":"2021-11-22T22:21:36.029892Z","iopub.status.idle":"2021-11-22T22:21:37.834887Z","shell.execute_reply.started":"2021-11-22T22:21:36.029857Z","shell.execute_reply":"2021-11-22T22:21:37.833938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_bgr: np.array = cv2.imread('../input/tensorflow-great-barrier-reef/train_images/video_1/10004.jpg')  # HxWxC / np.uint8\nimg_rgb: np.array = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)\n\nplt.imshow(img_rgb); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:24:18.035176Z","iopub.execute_input":"2021-11-22T22:24:18.035569Z","iopub.status.idle":"2021-11-22T22:24:18.438573Z","shell.execute_reply.started":"2021-11-22T22:24:18.035534Z","shell.execute_reply":"2021-11-22T22:24:18.437660Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Load an image with Torchvision\n\nIt returns the images in a torch.Tensor in the shape (C,H,W).","metadata":{}},{"cell_type":"code","source":"x_rgb: torch.tensor = torchvision.io.read_image('../input/tensorflow-great-barrier-reef/train_images/video_1/10004.jpg')  # CxHxW / torch.uint8\nx_rgb = x_rgb.unsqueeze(0)  # BxCxHxW\nprint(x_rgb.shape);","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:25:17.965549Z","iopub.execute_input":"2021-11-22T22:25:17.966057Z","iopub.status.idle":"2021-11-22T22:25:18.006799Z","shell.execute_reply.started":"2021-11-22T22:25:17.966015Z","shell.execute_reply":"2021-11-22T22:25:18.005760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Load an image with Kornia\n\n\"The utility is kornia.image_to_tensor which casts a numpy.ndarray to a torch.Tensor and permutes the channels to leave the image ready for being used with any other PyTorch or Kornia component. The image is casted into a 4D torch.Tensor with zero-copy.\"\n\nhttps://kornia-tutorials.readthedocs.io/en/latest/hello_world_tutorial.html","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/hello_world_tutorial.html\n\nx_bgr: torch.tensor = K.image_to_tensor(img_bgr)  # CxHxW / torch.uint8\nx_bgr = x_bgr.unsqueeze(0)  # 1xCxHxW\nprint(f\"convert from '{img_bgr.shape}' to '{x_bgr.shape}'\")","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:26:09.324233Z","iopub.execute_input":"2021-11-22T22:26:09.325430Z","iopub.status.idle":"2021-11-22T22:26:09.335194Z","shell.execute_reply.started":"2021-11-22T22:26:09.325349Z","shell.execute_reply":"2021-11-22T22:26:09.334059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Convert from BGR to RGB with a kornia.color component.","metadata":{}},{"cell_type":"code","source":"x_rgb: torch.tensor = K.color.bgr_to_rgb(x_bgr)  # 1xCxHxW / torch.uint8","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:27:10.771881Z","iopub.execute_input":"2021-11-22T22:27:10.772199Z","iopub.status.idle":"2021-11-22T22:27:10.780420Z","shell.execute_reply.started":"2021-11-22T22:27:10.772165Z","shell.execute_reply":"2021-11-22T22:27:10.779487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Visualize an image with Matplotib","metadata":{}},{"cell_type":"code","source":"img_bgr: np.array = K.tensor_to_image(x_bgr)\nimg_rgb: np.array = K.tensor_to_image(x_rgb)","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:27:53.711052Z","iopub.execute_input":"2021-11-22T22:27:53.711613Z","iopub.status.idle":"2021-11-22T22:27:53.719282Z","shell.execute_reply.started":"2021-11-22T22:27:53.711563Z","shell.execute_reply":"2021-11-22T22:27:53.718519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/hello_world_tutorial.html\n\nfig, axs = plt.subplots(1, 2, figsize=(32, 16))\naxs = axs.ravel()\n\naxs[0].axis('off')\naxs[0].imshow(img_rgb)\n\naxs[1].axis('off')\naxs[1].imshow(img_bgr)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-22T22:28:29.591739Z","iopub.execute_input":"2021-11-22T22:28:29.592034Z","iopub.status.idle":"2021-11-22T22:28:30.478213Z","shell.execute_reply.started":"2021-11-22T22:28:29.592005Z","shell.execute_reply":"2021-11-22T22:28:30.477065Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_augmentation_sequential.html?highlight=bbox\n\nfrom kornia import augmentation as K\nfrom kornia.augmentation import AugmentationSequential\n#from kornia.geometry import bbox_to_mask   #Deprecated??\nfrom kornia.utils import image_to_tensor, tensor_to_image\nfrom torchvision.transforms import transforms\nfrom kornia.geometry.bbox import bbox_to_mask as _bbox_to_mask\n\nto_tensor = transforms.ToTensor()\nto_pil = transforms.ToPILImage()\n\ndef plot_resulting_image(img, bbox, keypoints, mask):\n    img = img * mask\n    img_draw = cv2.polylines(np.array(to_pil(img)), bbox.numpy(), isClosed=True, color=(255, 0, 0))\n    for k in keypoints[0]:\n        img_draw = cv2.circle(img_draw, tuple(k.numpy()[:2]), radius=6, color=(255, 0, 0), thickness=-1)\n    return img_draw\n\nimg = cv2.imread(\"../input/tensorflow-great-barrier-reef/train_images/video_1/10004.jpg\", cv2.IMREAD_COLOR)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nh, w = img.shape[:2]\n\nimg_tensor = image_to_tensor(img).float() / 255.\nplt.imshow(img); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:09:21.027202Z","iopub.execute_input":"2021-11-22T23:09:21.027740Z","iopub.status.idle":"2021-11-22T23:09:21.309533Z","shell.execute_reply.started":"2021-11-22T23:09:21.027698Z","shell.execute_reply":"2021-11-22T23:09:21.308879Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Define Augmentation Sequential and Different Labels","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_augmentation_sequential.html?highlight=bbox\n\naug_list = AugmentationSequential(\n    K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=1.0),\n    K.RandomAffine(360, [0.1, 0.1], [0.7, 1.2], [30., 50.], p=1.0),\n    K.RandomPerspective(0.5, p=1.0),\n    data_keys=[\"input\", \"bbox\", \"keypoints\", \"mask\"],\n    return_transform=False,\n    same_on_batch=False,\n)\n\nbbox = torch.tensor([[[355,10],[660,10],[660,250],[355,250]]])\nkeypoints = torch.tensor([[[465, 115], [545, 116]]])\nmask = bbox_to_mask(torch.tensor([[[155,0],[900,0],[900,400],[155,400]]]), w, h).float()\n\nimg_out = plot_resulting_image(img_tensor, bbox, keypoints, mask)\nplt.imshow(img_out); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:09:26.163792Z","iopub.execute_input":"2021-11-22T23:09:26.164604Z","iopub.status.idle":"2021-11-22T23:09:26.418330Z","shell.execute_reply.started":"2021-11-22T23:09:26.164547Z","shell.execute_reply":"2021-11-22T23:09:26.417647Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I tried from kornia.geometry.bbox import bbox_to_mask as _bbox_to_mask  Though the warning above persists. ","metadata":{}},{"cell_type":"markdown","source":"#Forward Computations","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_augmentation_sequential.html?highlight=bbox\n\nout_tensor = aug_list(img_tensor, bbox.float(), keypoints.float(), mask)\nimg_out = plot_resulting_image(\n    out_tensor[0][0],\n    out_tensor[1].int(),\n    out_tensor[2].int(),\n    out_tensor[3][0],\n)\nplt.imshow(img_out); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:09:38.665460Z","iopub.execute_input":"2021-11-22T23:09:38.666275Z","iopub.status.idle":"2021-11-22T23:09:39.358150Z","shell.execute_reply.started":"2021-11-22T23:09:38.666227Z","shell.execute_reply":"2021-11-22T23:09:39.357011Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Inverse Transformations","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_augmentation_sequential.html?highlight=bbox\n\nout_tensor_inv = aug_list.inverse(*out_tensor)\nimg_out = plot_resulting_image(\n    out_tensor_inv[0][0],\n    out_tensor_inv[1].int(),\n    out_tensor_inv[2].int(),\n    out_tensor_inv[3][0],\n)\nplt.imshow(img_out); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:09:45.113485Z","iopub.execute_input":"2021-11-22T23:09:45.113786Z","iopub.status.idle":"2021-11-22T23:09:45.529972Z","shell.execute_reply.started":"2021-11-22T23:09:45.113755Z","shell.execute_reply":"2021-11-22T23:09:45.528787Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"to_tensor = transforms.ToTensor()\nto_pil = transforms.ToPILImage()\n\n\ndef plot_resulting_image(img, bbox, keypoints, mask):\n    img = img * mask\n    img_draw = cv2.polylines(np.array(to_pil(img)), bbox.numpy(), isClosed=True, color=(255, 0, 0))\n    for k in keypoints[0]:\n        img_draw = cv2.circle(img_draw, tuple(k.numpy()[:2]), radius=6, color=(255, 0, 0), thickness=-1)\n    return img_draw\n\nimg = cv2.imread(\"../input/tensorflow-great-barrier-reef/train_images/video_2/100.jpg\", cv2.IMREAD_COLOR)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nh, w = img.shape[:2]\n\nimg_tensor = image_to_tensor(img).float() / 255.\nplt.imshow(img); plt.axis('off');","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:13:37.273347Z","iopub.execute_input":"2021-11-22T23:13:37.274098Z","iopub.status.idle":"2021-11-22T23:13:37.560436Z","shell.execute_reply.started":"2021-11-22T23:13:37.274054Z","shell.execute_reply":"2021-11-22T23:13:37.559493Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Patch Augmentation Sequential with patchwise_apply=True","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_patch_sequential.html\n\nfrom kornia.augmentation import PatchSequential, ImageSequential\n\npseq = PatchSequential(\n    ImageSequential(\n        K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n        K.RandomPerspective(0.2, p=0.5),\n        K.RandomSolarize(0.1, 0.1, p=0.5),\n    ),\n    K.RandomAffine(15, [0.1, 0.1], [0.7, 1.2], [0., 20.], p=0.5),\n    K.RandomPerspective(0.2, p=0.5),\n    ImageSequential(\n        K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n        K.RandomPerspective(0.2, p=0.5),\n        K.RandomSolarize(0.1, 0.1, p=0.5),\n    ),\n    K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n    K.RandomAffine(15, [0.1, 0.1], [0.7, 1.2], [0., 20.], p=0.5),\n    K.RandomPerspective(0.2, p=0.5),\n    K.RandomSolarize(0.1, 0.1, p=0.5),\n    K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n    K.RandomAffine(15, [0.1, 0.1], [0.7, 1.2], [0., 20.], p=0.5),\n    ImageSequential(\n        K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n        K.RandomPerspective(0.2, p=0.5),\n        K.RandomSolarize(0.1, 0.1, p=0.5),\n    ),\n    K.RandomSolarize(0.1, 0.1, p=0.5),\n    K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.5),\n    K.RandomAffine(15, [0.1, 0.1], [0.7, 1.2], [0., 20.], p=0.5),\n    K.RandomPerspective(0.2, p=0.5),\n    K.RandomSolarize(0.1, 0.1, p=0.5),\n    patchwise_apply=True,\n    same_on_batch=True,\n)\nout_tensor = pseq(img_tensor[None].repeat(2, 1, 1, 1))\nto_pil(torch.cat([out_tensor[0], out_tensor[1]], dim=2))","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:15:20.877270Z","iopub.execute_input":"2021-11-22T23:15:20.877866Z","iopub.status.idle":"2021-11-22T23:15:21.548977Z","shell.execute_reply.started":"2021-11-22T23:15:20.877827Z","shell.execute_reply":"2021-11-22T23:15:21.547777Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Patch Augmentation Sequential with patchwise_apply=False","metadata":{}},{"cell_type":"code","source":"#Code by https://kornia-tutorials.readthedocs.io/en/latest/data_patch_sequential.html\n\npseq = PatchSequential(\n    K.ColorJitter(0.1, 0.1, 0.1, 0.1, p=0.75),\n    K.RandomElasticTransform(alpha=(4., 4.)),\n    patchwise_apply=False,\n    same_on_batch=False\n)\nout_tensor = pseq(img_tensor[None].repeat(2, 1, 1, 1))\nto_pil(torch.cat([out_tensor[0], out_tensor[1]], dim=2))","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:16:32.458218Z","iopub.execute_input":"2021-11-22T23:16:32.458523Z","iopub.status.idle":"2021-11-22T23:16:36.502703Z","shell.execute_reply.started":"2021-11-22T23:16:32.458488Z","shell.execute_reply":"2021-11-22T23:16:36.501436Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#Acknowledgement:\n\n@inproceedings{eriba2020kornia, author = {E. Riba, D. Mishkin, J. Shi, D. Ponsa, F. Moreno-Noguer and G. Bradski}, title = {A survey on Kornia: an Open Source Differentiable Computer Vision Library for PyTorch}, year = {2020}, }\n\n@inproceedings{eriba2019kornia, author = {E. Riba, D. Mishkin, D. Ponsa, E. Rublee and G. Bradski}, title = {Kornia: an Open Source Differentiable Computer Vision Library for PyTorch}, booktitle = {Winter Conference on Applications of Computer Vision}, year = {2020}, url = {https://arxiv.org/pdf/1910.02190.pdf} }\n\n@misc{Arraiy2018, author = {E. Riba, M. Fathollahi, W. Chaney, E. Rublee and G. Bradski}, title = {torchgeometry: when PyTorch meets geometry}, booktitle = {PyTorch Developer Conference}, year = {2018}, url = {https://drive.google.com/file/d/1xiao1Xj9WzjJ08YY_nYwsthE-wxfyfhG/view?usp=sharing} }","metadata":{}},{"cell_type":"markdown","source":"#Though it's TensorFlow Competition, I made a Kaggle Notebook with a library that uses PyTorch (awkward situation).","metadata":{"execution":{"iopub.status.busy":"2021-11-22T23:38:48.385961Z","iopub.execute_input":"2021-11-22T23:38:48.386269Z","iopub.status.idle":"2021-11-22T23:38:56.144237Z","shell.execute_reply.started":"2021-11-22T23:38:48.386241Z","shell.execute_reply":"2021-11-22T23:38:56.143283Z"},"_kg_hide-output":true}}]}