{"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 os\nimport cv2\nfrom tqdm.auto import tqdm\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom tensorflow import keras\n\nimport keras_cv\nfrom keras_cv import bounding_box\nfrom keras_cv import visualization","metadata":{"execution":{"iopub.status.busy":"2023-08-16T20:42:48.637085Z","iopub.execute_input":"2023-08-16T20:42:48.637778Z","iopub.status.idle":"2023-08-16T20:42:48.643965Z","shell.execute_reply.started":"2023-08-16T20:42:48.637743Z","shell.execute_reply":"2023-08-16T20:42:48.642763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SPLIT_RATIO = 0.2\nBATCH_SIZE = 4\nLEARNING_RATE = 0.001\nEPOCH = 5\nGLOBAL_CLIPNORM = 10.0","metadata":{"execution":{"iopub.status.busy":"2023-08-16T20:42:52.54032Z","iopub.execute_input":"2023-08-16T20:42:52.540795Z","iopub.status.idle":"2023-08-16T20:42:52.546285Z","shell.execute_reply.started":"2023-08-16T20:42:52.540757Z","shell.execute_reply":"2023-08-16T20:42:52.54513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Path to images and annotations\npath_images = \"/kaggle/input/airbus-ship-detection/train_v2/\"\npath_annot = \"/kaggle/input/dataset/data/annotations/\"\n","metadata":{"execution":{"iopub.status.busy":"2023-08-16T20:42:54.937405Z","iopub.execute_input":"2023-08-16T20:42:54.938409Z","iopub.status.idle":"2023-08-16T20:42:54.943943Z","shell.execute_reply.started":"2023-08-16T20:42:54.938354Z","shell.execute_reply":"2023-08-16T20:42:54.942727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare annotations\n\n# Open data\nwith open(\"/kaggle/input/airbus-ship-detection/train_ship_segmentations_v2.csv\", 'r') as f:\n    annotations = f.read().split('\\n')\n    annotations = [a.split(',') for a in annotations]\n    annotations = annotations[1:-1]\n\n\n# Create dictionary of rle annotation strings\nannot_dict = {}\nfor i, p in annotations:\n    if i not in annot_dict:\n        if p:\n            annot_dict[i] = [p]\n        else:\n            annot_dict[i] = []\n    else:\n        if p:\n            annot_dict[i].append(p)\n        else:\n            assert False\n\n\n# Build a function to turn rle into bounding box in xyxy format.\ndef rle2bbox(rle, shape):\n    # The rle string comes in sets of (start, lenght) pairs referring to pixel \n    # positions in the flattened array.\n    rle = np.array(rle.split()).reshape(-1, 2).astype(int)\n    \n    # Adjust intial pixel, since rle is one indexing\n    rle[:, 0] -= 1\n    # Tuen length into end pixel positions\n    rle[:, 1] = rle[:, 0] + (rle[:, 1] - 1)\n    \n    # Get y values by finding how many rows we need to reach position\n    yvals = rle // shape[1]\n    assert np.all(yvals[:, 0] == yvals[:, 1])\n    ymin = yvals.min()\n    ymax = yvals.max()\n    assert ymax <= shape[0]\n    \n    # Get the x values using modulus, position along a row\n    xvals = rle % shape[1]\n    assert np.all(xvals[:, 0] <= xvals[:, 1])\n    xmin = xvals.min()\n    xmax = xvals.max()\n    \n    # Return the bounding box in xyxy format\n    return (ymin, xmin, ymax, xmax)\n\n# Create dictionary of bounding boxes\nshape = (768, 768, 3)\nbbox_dict = {i: list(map(rle2bbox, rle, [shape]*len(rle)))\n             for i, rle in annot_dict.items()}\n\n# Create the requiered lists of image paths, bbox lists and classes\nimage_paths = [path_images + k for k in bbox_dict.keys()]\nbbox = list(bbox_dict.values())\nclasses = [[1]*len(bb) for bb in bbox]\n\n# Use ragged tensors to account for different number of ships per image\nbbox = tf.ragged.constant(bbox)\nclasses = tf.ragged.constant(classes)\nimage_paths = tf.ragged.constant(image_paths)\n\ndata = tf.data.Dataset.from_tensor_slices((image_paths, classes, bbox))","metadata":{"execution":{"iopub.status.busy":"2023-08-16T20:42:57.237951Z","iopub.execute_input":"2023-08-16T20:42:57.238376Z","iopub.status.idle":"2023-08-16T20:43:18.385995Z","shell.execute_reply.started":"2023-08-16T20:42:57.238343Z","shell.execute_reply":"2023-08-16T20:43:18.385075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Determine the number of validation samples\nnum_val = int(len(image_paths) * SPLIT_RATIO)\n\n# Split the dataset into train and validation sets\nval_data = data.take(num_val)\ntrain_data = data.skip(num_val)","metadata":{"execution":{"iopub.status.busy":"2023-08-16T20:43:23.807394Z","iopub.execute_input":"2023-08-16T20:43:23.807822Z","iopub.status.idle":"2023-08-16T20:43:23.8148Z","shell.execute_reply.started":"2023-08-16T20:43:23.80779Z","shell.execute_reply":"2023-08-16T20:43:23.813476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def filter_image_processed(image):\n    filtered_image=image\n    filtered_image= tf.image.convert_image_dtype(filtered_image, tf.float32)\n    \n    filtered_image=tf.image.adjust_contrast(filtered_image, contrast_factor=1)\n    filtered_image=tf.image.adjust_brightness(filtered_image, max_delta=0.2)\n    \n    intensity ratio=0.8\n    filtered_image=tf.clip_by_value(filtered_image*intensity_ratio, 0.0, 1.0)\n    \n    gamma= 1.5\n    filtered_image=tf.pow(filtered_image, gamma)\n    \n    filtered_image=tf.clip_by_value(filtered_image, 0.0, 0.1)\n    filtered_image=tf.image.convert_image_dtype(filtered_image, tf.uint8)\n    \n    return filtered_image\n\ndef load_image(image_path):\n    image = tf.io.read_file(image_path)\n    image = tf.image.decode_jpeg(image, channels=3)\n    \n    filtered_image= filter_image_processed(image)\n    \n    return [image, filtered_image]\n\n\ndef load_dataset(image_path, classes, bbox):\n    # Read Image\n    image = load_image(image_path)\n    bounding_boxes = {\n        \"classes\": tf.cast(classes, dtype=tf.float32),\n        \"boxes\": bbox,\n    }\n    return {\"images\": tf.cast(image, tf.float32), \"bounding_boxes\": bounding_boxes}\n\ndef load_filtered_dataset(image_path, classes, bbox):\n    image = load_image(image_path)[1]\n        bounding_boxes = {\n        \"classes\": tf.cast(classes, dtype=tf.float32),\n        \"boxes\": bbox,\n    }\n    return {\"images\": tf.cast(image, tf.float32), \"bounding_boxes\": bounding_boxes}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data augmentation\naugmenter = keras.Sequential(\n    layers=[\n        keras_cv.layers.RandomFlip(mode=\"horizontal\", bounding_box_format=\"xyxy\"),\n        keras_cv.layers.RandomShear(\n            x_factor=0.2, y_factor=0.2, bounding_box_format=\"xyxy\"\n        ),\n        keras_cv.layers.JitteredResize(\n            target_size=(640, 640), scale_factor=(0.75, 1.3), bounding_box_format=\"xyxy\"\n        ),\n    ]\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-16T22:50:42.6418Z","iopub.execute_input":"2023-08-16T22:50:42.642197Z","iopub.status.idle":"2023-08-16T22:50:42.65669Z","shell.execute_reply.started":"2023-08-16T22:50:42.642166Z","shell.execute_reply":"2023-08-16T22:50:42.655422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training data set\ntrain_ds = train_data.map(load_filtered_dataset, num_parallel_calls=tf.data.AUTOTUNE)\ntrain_ds = train_ds.shuffle(BATCH_SIZE * 4)\ntrain_ds = train_ds.ragged_batch(BATCH_SIZE, drop_remainder=True)\ntrain_ds = train_ds.map(augmenter, num_parallel_calls=tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-08-16T22:50:45.906855Z","iopub.execute_input":"2023-08-16T22:50:45.907318Z","iopub.status.idle":"2023-08-16T22:50:48.036181Z","shell.execute_reply.started":"2023-08-16T22:50:45.907279Z","shell.execute_reply":"2023-08-16T22:50:48.035192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Validation data set\nresizing = keras_cv.layers.JitteredResize(\n    target_size=(640, 640),\n    scale_factor=(0.75, 1.3),\n    bounding_box_format=\"xyxy\",\n)\n\nval_ds = val_data.map(load_dataset, num_parallel_calls=tf.data.AUTOTUNE)\nval_ds = val_ds.shuffle(BATCH_SIZE * 4)\nval_ds = val_ds.ragged_batch(BATCH_SIZE, drop_remainder=True)\nval_ds = val_ds.map(resizing, num_parallel_calls=tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-08-16T22:50:49.835563Z","iopub.execute_input":"2023-08-16T22:50:49.836719Z","iopub.status.idle":"2023-08-16T22:50:50.64195Z","shell.execute_reply.started":"2023-08-16T22:50:49.836678Z","shell.execute_reply":"2023-08-16T22:50:50.640805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualization\ndef visualize_dataset(inputs, value_range, rows, cols, bounding_box_format):\n    inputs = next(iter(inputs.take(1)))\n    images, bounding_boxes = inputs[\"images\"], inputs[\"bounding_boxes\"]\n    visualization.plot_bounding_box_gallery(\n        images,\n        value_range=value_range,\n        rows=rows,\n        cols=cols,\n        y_true=bounding_boxes,\n        scale=5,\n        font_scale=0.7,\n        bounding_box_format=bounding_box_format,\n        class_mapping={1: 'Boat'},\n    )\n\n\nvisualize_dataset(\n    train_ds, bounding_box_format=\"xyxy\", value_range=(0, 255), rows=2, cols=2\n)\n\nvisualize_dataset(\n    val_ds, bounding_box_format=\"xyxy\", value_range=(0, 255), rows=2, cols=2\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-16T22:50:53.143426Z","iopub.execute_input":"2023-08-16T22:50:53.144444Z","iopub.status.idle":"2023-08-16T22:50:57.483032Z","shell.execute_reply.started":"2023-08-16T22:50:53.144402Z","shell.execute_reply":"2023-08-16T22:50:57.482106Z"},"trusted":true},"execution_count":null,"outputs":[]}]}