forked from jackliu333/object_detection_using_tensorflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "bc9a8df0", | ||
"metadata": {}, | ||
"source": [ | ||
"# Image Tiler\n", | ||
"\n", | ||
"Tile larger images into smaller images\n", | ||
"\n", | ||
"This involves cutting up the images into smaller ovelapping images" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "33a385ba", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Current OS: posix\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import numpy as np\n", | ||
"import matplotlib.pyplot as plt\n", | ||
"\n", | ||
"import io\n", | ||
"import PIL\n", | ||
"from PIL import Image\n", | ||
"\n", | ||
"import os\n", | ||
"print(f\"Current OS: {os.name}\") " | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "fbb2db88", | ||
"metadata": {}, | ||
"source": [ | ||
"## Utils" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "b3ab1ec3", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def counter(start = None):\n", | ||
" if start == None:\n", | ||
" count = 0\n", | ||
" else:\n", | ||
" count = start\n", | ||
" def increment(cmd = None):\n", | ||
" nonlocal count\n", | ||
" if cmd == 'READ':\n", | ||
" #no imcreament, just read the count\n", | ||
" cmd = None\n", | ||
" else:\n", | ||
" if cmd == None:\n", | ||
" count += 1\n", | ||
" else:\n", | ||
" count = cmd\n", | ||
" cmd = None\n", | ||
" return count\n", | ||
" return increment" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "fed0741f", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def filename_append(filename, append_text):\n", | ||
" old_file = os.path.splitext(filename)\n", | ||
" new_file_name = old_file[0]+'_'+str(append_text)+old_file[1]\n", | ||
" return new_file_name" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "2db62aca", | ||
"metadata": { | ||
"scrolled": true | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"# Create image tiles\n", | ||
"# Refer to the following for info about the image orientation attribute\n", | ||
"# https://gigazine.net/gsc_news/en/20191208-python-exif-orientation/\n", | ||
"\n", | ||
"def tile_image(src_dir_entry, dst_image_folder, counters, crop_size=[1000, 1000], crop_overlap = 200):\n", | ||
" \" \\\n", | ||
" src_dir_entry = the directory entry to the source image file \\\n", | ||
" dst_image_folder = the path to the save folder for the new image tiles \\\n", | ||
" counters = A dict containg: SRC_IMAGE_COUNTER, TILE_IMAGE_COUNTER, ANNOTATION_COUNTER. \\\n", | ||
" crop_size = [width, height] the width and height of the output images. \\\n", | ||
" crop_overlap = an int value that is used to overlap the tiles. \"\n", | ||
" \n", | ||
" img_count = counters['SRC_IMAGE_COUNTER']()\n", | ||
"\n", | ||
" # Retrieve the image\n", | ||
" image_raw = Image.open(src_dir_entry.path)\n", | ||
" image = PIL.ImageOps.exif_transpose(image_raw) #Correct image orientation\n", | ||
" image_size = image.size\n", | ||
" \n", | ||
" # iterate over image X and Y\n", | ||
" for x in range(0, image.size[0]-crop_overlap, crop_size[0]-crop_overlap): #(Start, End, Step)\n", | ||
" if x >= image_size[0]-crop_size[0]: #Adjust for end case\n", | ||
" x = image_size[0]-crop_size[0]\n", | ||
" for y in range(0, image.size[1]-crop_overlap, crop_size[1]-crop_overlap): #(Start, End, Step)\n", | ||
" if y >= image_size[1]-crop_size[1]: #Adjust for end case\n", | ||
" y = image_size[1]-crop_size[1]\n", | ||
"\n", | ||
" new_image_id = counters['TILE_IMAGE_COUNTER']()\n", | ||
"\n", | ||
" crop_box = (x, y, x+crop_size[0], y+crop_size[1])\n", | ||
"\n", | ||
" # Insert the new_image_id into the file name to create a new file name for each tile\n", | ||
" new_filename = os.path.join(paths['IMAGE_DST_PATH'], filename_append(src_dir_entry.name, str(new_image_id)))\n", | ||
" # Save the cropped image to the updated filename\n", | ||
" image.crop(crop_box).save(new_filename)\n", | ||
" return" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "202d6c3d", | ||
"metadata": {}, | ||
"source": [ | ||
"## Process images" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "734aba60", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Define a list of folder paths to be created (if needed) and used later\n", | ||
"root_dir = os.path.join('/workspace', 'data', 'NZRC', 'Gordon', 'CycloneGitaRawImagery')\n", | ||
"\n", | ||
"paths = {\n", | ||
" 'ROOT_PATH' : root_dir,\n", | ||
" 'IMAGE_SRC_PATH' : os.path.join(root_dir,'ML4DR_images', 'Test'),\n", | ||
" 'IMAGE_DST_PATH' : os.path.join(root_dir, 'ML4DR_images', 'Test', 'tiles'),\n", | ||
"}\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"id": "dfcecacd", | ||
"metadata": { | ||
"scrolled": true | ||
}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_1_Images_Flight_1_DSC09249_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_19_DSC09200_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_19_DSC09948_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_20_DSC09648_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_20_DSC09787_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_20_DSC09789_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_20_DSC09793_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/Day_6_Images_Flight_20_DSC09807_geotag.JPG True\n", | ||
"/workspace/data/NZRC/Gordon/CycloneGitaRawImagery/ML4DR_images/Test/tiles False\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"# Display an imageInfo record and the image\n", | ||
"\n", | ||
"# Set counters\n", | ||
"counters={'SRC_IMAGE_COUNTER':counter(0), 'TILE_IMAGE_COUNTER':counter(0)}\n", | ||
"\n", | ||
"crop_size = [1000, 1000]\n", | ||
"crop_overlap = 200\n", | ||
"j = 0\n", | ||
"\n", | ||
"#image_file_list = os.listdir(paths['IMAGE_SRC_PATH'])\n", | ||
"image_file_list = os.scandir(paths['IMAGE_SRC_PATH'])\n", | ||
"\n", | ||
"for image_file in image_file_list:\n", | ||
" if image_file.is_file():\n", | ||
" tile_image(image_file, paths['IMAGE_DST_PATH'], counters, crop_size, crop_overlap)\n", | ||
"\n" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.8.10" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |