kopia lustrzana https://github.com/OpenDroneMap/ODM
commit
1042e50a49
|
@ -19,7 +19,7 @@ ExternalProject_Add(${_proj_name}
|
|||
#--Download step--------------
|
||||
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
|
||||
GIT_REPOSITORY https://github.com/OpenDroneMap/OpenSfM/
|
||||
GIT_TAG 262
|
||||
GIT_TAG 263
|
||||
#--Update/Patch step----------
|
||||
UPDATE_COMMAND git submodule update --init --recursive
|
||||
#--Configure step-------------
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# Resize
|
||||
|
||||
Resize a dataset (and optional GCP file).
|
||||
|
||||
Resizes images, keeps Exif data. The EXIF width and height attributes will be updated accordingly also. ODM GCP files are scaled also.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
python3 resize.py -i images/ -o resized/ 25%
|
||||
python3 resize.py -i images/1.JPG -o resized.JPG 25%
|
||||
python3 resize.py -i gcp_list.txt -o resized_gcp_list.txt
|
||||
```
|
||||
|
||||
Originally forked from https://github.com/pierotofy/exifimageresize
|
|
@ -0,0 +1,2 @@
|
|||
Pillow==8.0.1
|
||||
piexif==1.1.2
|
|
@ -0,0 +1,169 @@
|
|||
import argparse
|
||||
import os
|
||||
import glob
|
||||
import shutil
|
||||
from PIL import Image
|
||||
import piexif
|
||||
import multiprocessing
|
||||
from multiprocessing.pool import ThreadPool
|
||||
import sys
|
||||
sys.path.append("../../")
|
||||
from opendm.gcp import GCPFile
|
||||
|
||||
parser = argparse.ArgumentParser(description='Exif Image Resize')
|
||||
parser.add_argument('--input', '-i',
|
||||
metavar='<path>',
|
||||
required=True,
|
||||
help='Path to input image/GCP or image folder')
|
||||
parser.add_argument('--output', '-o',
|
||||
metavar='<path>',
|
||||
required=True,
|
||||
help='Path to output image/GCP or image folder')
|
||||
parser.add_argument('--force', '-f',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Overwrite results')
|
||||
parser.add_argument('amount',
|
||||
metavar='<pixel|percentage%>',
|
||||
type=str,
|
||||
help='Pixel of largest side or percentage to resize images by')
|
||||
args = parser.parse_args()
|
||||
|
||||
def die(msg):
|
||||
print(msg)
|
||||
exit(1)
|
||||
|
||||
class nonloc:
|
||||
errors = 0
|
||||
|
||||
def resize_image(image_path, out_path, resize_to, out_path_is_file=False):
|
||||
"""
|
||||
:param image_path: path to the image
|
||||
:param out_path: path to the output directory or file
|
||||
:param resize_to: percentage ("perc%") or pixels
|
||||
"""
|
||||
try:
|
||||
im = Image.open(image_path)
|
||||
path, ext = os.path.splitext(image_path)
|
||||
if out_path_is_file:
|
||||
resized_image_path = out_path
|
||||
else:
|
||||
resized_image_path = os.path.join(out_path, os.path.basename(image_path))
|
||||
|
||||
width, height = im.size
|
||||
max_side = max(width, height)
|
||||
|
||||
if isinstance(resize_to, str) and resize_to.endswith("%"):
|
||||
ratio = float(resize_to[:-1]) / 100.0
|
||||
else:
|
||||
ratio = float(resize_to) / float(max_side)
|
||||
|
||||
resized_width = int(width * ratio)
|
||||
resized_height = int(height * ratio)
|
||||
|
||||
im.thumbnail((resized_width, resized_height), Image.LANCZOS)
|
||||
|
||||
driver = ext[1:].upper()
|
||||
if driver == 'JPG':
|
||||
driver = 'JPEG'
|
||||
|
||||
if 'exif' in im.info:
|
||||
exif_dict = piexif.load(im.info['exif'])
|
||||
exif_dict['Exif'][piexif.ExifIFD.PixelXDimension] = resized_width
|
||||
exif_dict['Exif'][piexif.ExifIFD.PixelYDimension] = resized_height
|
||||
im.save(resized_image_path, driver, exif=piexif.dump(exif_dict), quality=100)
|
||||
else:
|
||||
im.save(resized_image_path, driver, quality=100)
|
||||
|
||||
im.close()
|
||||
|
||||
print("{} ({}x{}) --> {} ({}x{})".format(image_path, width, height, resized_image_path, resized_width, resized_height))
|
||||
except (IOError, ValueError) as e:
|
||||
print("Error: Cannot resize {}: {}.".format(image_path, str(e)))
|
||||
nonloc.errors += 1
|
||||
|
||||
def resize_gcp(gcp_path, out_path, resize_to, out_path_is_file=False):
|
||||
"""
|
||||
:param gcp_path: path to the GCP
|
||||
:param out_path: path to the output directory or file
|
||||
:param resize_to: percentage ("perc%") or pixels
|
||||
"""
|
||||
try:
|
||||
if out_path_is_file:
|
||||
resized_gcp_path = out_path
|
||||
else:
|
||||
resized_gcp_path = os.path.join(out_path, os.path.basename(gcp_path))
|
||||
|
||||
if resize_to.endswith("%"):
|
||||
ratio = float(resize_to[:-1]) / 100.0
|
||||
else:
|
||||
ratio = resize_to
|
||||
|
||||
gcp = GCPFile(gcp_path)
|
||||
if gcp.entries_count() > 0:
|
||||
gcp.make_resized_copy(resized_gcp_path, ratio)
|
||||
else:
|
||||
raise ValueError("No GCP entries")
|
||||
|
||||
print("{} --> {}".format(gcp_path, resized_gcp_path))
|
||||
except (IOError, ValueError) as e:
|
||||
print("Error: Cannot resize {}: {}.".format(gcp_path, str(e)))
|
||||
nonloc.errors += 1
|
||||
|
||||
if not args.amount.endswith("%"):
|
||||
args.amount = float(args.amount)
|
||||
if args.amount <= 0:
|
||||
die("Invalid amount")
|
||||
else:
|
||||
try:
|
||||
if float(args.amount[:-1]) <= 0:
|
||||
die("Invalid amount")
|
||||
except:
|
||||
die("Invalid amount")
|
||||
|
||||
|
||||
files = []
|
||||
gcps = []
|
||||
|
||||
if os.path.isdir(args.input):
|
||||
for ext in ["JPG", "JPEG", "PNG", "TIFF", "TIF"]:
|
||||
files += glob.glob("{}/*.{}".format(args.input, ext))
|
||||
files += glob.glob("{}/*.{}".format(args.input, ext.lower()))
|
||||
gcps = glob.glob("{}/*.txt".format(args.input))
|
||||
elif os.path.exists(args.input):
|
||||
_, ext = os.path.splitext(args.input)
|
||||
if ext.lower() == ".txt":
|
||||
gcps = [args.input]
|
||||
else:
|
||||
files = [args.input]
|
||||
else:
|
||||
die("{} does not exist".format(args.input))
|
||||
|
||||
create_dir = len(files) > 1 or args.output.endswith("/") or len(gcps) > 1
|
||||
|
||||
if create_dir and os.path.isdir(args.output):
|
||||
if not args.force:
|
||||
die("{} exists, pass --force to overwrite results".format(args.output))
|
||||
else:
|
||||
shutil.rmtree(args.output)
|
||||
elif not create_dir and os.path.isfile(args.output):
|
||||
if not args.force:
|
||||
die("{} exists, pass --force to overwrite results".format(args.output))
|
||||
else:
|
||||
os.remove(args.output)
|
||||
|
||||
if create_dir:
|
||||
os.makedirs(args.output)
|
||||
|
||||
pool = ThreadPool(processes=multiprocessing.cpu_count())
|
||||
|
||||
def resize(file):
|
||||
_, ext = os.path.splitext(file)
|
||||
if ext.lower() == ".txt":
|
||||
return resize_gcp(file, args.output, args.amount, not create_dir)
|
||||
else:
|
||||
return resize_image(file, args.output, args.amount, not create_dir)
|
||||
pool.map(resize, files + gcps)
|
||||
|
||||
print("Process completed, {} errors.".format(nonloc.errors))
|
||||
|
|
@ -51,6 +51,25 @@ class GCPFile:
|
|||
def exists(self):
|
||||
return bool(self.gcp_path and os.path.exists(self.gcp_path))
|
||||
|
||||
def make_resized_copy(self, gcp_file_output, ratio):
|
||||
"""
|
||||
Creates a new resized GCP file from an existing GCP file. If one already exists, it will be removed.
|
||||
:param gcp_file_output output path of new GCP file
|
||||
:param ratio scale GCP coordinates by this value
|
||||
:return path to new GCP file
|
||||
"""
|
||||
output = [self.raw_srs]
|
||||
|
||||
for entry in self.iter_entries():
|
||||
entry.px *= ratio
|
||||
entry.py *= ratio
|
||||
output.append(str(entry))
|
||||
|
||||
with open(gcp_file_output, 'w') as f:
|
||||
f.write('\n'.join(output) + '\n')
|
||||
|
||||
return gcp_file_output
|
||||
|
||||
def wgs84_utm_zone(self):
|
||||
"""
|
||||
Finds the UTM zone where the first point of the GCP falls into
|
||||
|
|
Ładowanie…
Reference in New Issue