Skip to content

Commit

Permalink
Fix unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Courroux committed Feb 5, 2024
1 parent eeaf6e8 commit dfc8ac0
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 71 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ before_install:
# install library dependencies
- sudo apt-get install libzbar0 make perl
# Install exiftool
- wget https://cpan.metacpan.org/authors/id/E/EX/EXIFTOOL/Image-ExifTool-12.15.tar.gz
- tar -xzf Image-ExifTool-12.15.tar.gz
- pushd Image-ExifTool-12.15/
- perl Makefile.PL
- wget https://cpan.metacpan.org/authors/id/E/EX/EXIFTOOL/Image-ExifTool-12.76.tar.gz
- tar -xzf Image-ExifTool-12.76.tar.gz
- pushd Image-ExifTool-12.76/
- perl Makefile.PL
- make test
- sudo make install
- popd
Expand Down
6 changes: 3 additions & 3 deletions micasense/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Image(object):
band of multispectral information
"""

def __init__(self, image_path, exiftool_obj=None, allow_uncalibrated=False):
def __init__(self, image_path: str, exiftool_obj=None, allow_uncalibrated=False):
if not os.path.isfile(image_path):
raise IOError("Provided path is not a file: {}".format(image_path))
self.path = image_path
Expand Down Expand Up @@ -191,7 +191,7 @@ def compute_horizontal_irradiance_dls1(self):
return self.horizontal_irradiance_from_direct_scattered()

def compute_horizontal_irradiance_dls2(self):
""" Compute the proper solar elevation, solar azimuth, and horizontal irradiance
""" Compute the proper solar elevation, solar azimuth, and horizontal irradiance
for cases where the camera system did not do it correctly """
_, _, _, \
self.solar_elevation, \
Expand Down Expand Up @@ -373,7 +373,7 @@ def vignette(self):
yv = y.T / y_dim
k = self.vignette_polynomial2D
e = self.vignette_polynomial2Dexponents
p2 = np.zeros_like(xv, dtype=np.float)
p2 = np.zeros_like(xv, dtype=float)
for i, c in enumerate(k):
ex = e[2 * i]
ey = e[2 * i + 1]
Expand Down
2 changes: 1 addition & 1 deletion micasense/imageset.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def from_directory(cls, directory, progress_callback=None, exiftool_path=None, a
if exiftool_path is None and os.environ.get('exiftoolpath') is not None:
exiftool_path = os.path.normpath(os.environ.get('exiftoolpath'))

with exiftool.ExifTool(exiftool_path) as exift:
with exiftool.ExifToolHelper(exiftool_path) as exift:
for i, path in enumerate(matches):
images.append(image.Image(path, exiftool_obj=exift, allow_uncalibrated=allow_uncalibrated))
if progress_callback is not None:
Expand Down
8 changes: 4 additions & 4 deletions micasense/imageutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ def min_max(pts):

def map_points(pts, image_size, warpMatrix, distortion_coeffs, camera_matrix, warp_mode=cv2.MOTION_HOMOGRAPHY):
# extra dimension makes opencv happy
pts = np.array([pts], dtype=np.float)
pts = np.array([pts], dtype=float)
new_cam_mat, _ = cv2.getOptimalNewCameraMatrix(camera_matrix, distortion_coeffs, image_size, 1)
new_pts = cv2.undistortPoints(pts, camera_matrix, distortion_coeffs, P=new_cam_mat)
if warp_mode == cv2.MOTION_AFFINE:
Expand Down Expand Up @@ -584,7 +584,7 @@ def radiometric_pan_sharpen(capture, warp_matrices=None, panchro_band=5, irradia
# this function performs a radiometrically accurate pansharpening on the input capture
# if no warp matrices are supplied to align the multispec images to the pan band
# the camera calibration is used (which produces reasonably well aligned imagers in most cases)
# in addition to the pan sharpened stack, the equivalent upsampled stack is also produced
# in addition to the pan sharpened stack, the equivalent upsampled stack is also produced
# for comparison
# use the warp matrices we have for the stack, if not user supplied
if warp_matrices is None:
Expand Down Expand Up @@ -654,9 +654,9 @@ def radiometric_pan_sharpen(capture, warp_matrices=None, panchro_band=5, irradia
def prepare_exif_for_stacks(thecapture, thefilename):
lat, lon, alt = thecapture.location()
resolution = thecapture.images[0].focal_plane_resolution_px_per_mm
# eventually it would be nice to add the capture ID, flight ID,
# eventually it would be nice to add the capture ID, flight ID,
# and yaw/pitch/roll, but these are non-standard exif tags,
# so it is more difficult.
# so it is more difficult.
attitude = thecapture.dls_pose()
theid = thecapture.uuid
flightid = thecapture.flightid
Expand Down
16 changes: 8 additions & 8 deletions micasense/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
class Metadata(object):
""" Container for Micasense image metadata"""

def __init__(self, filename, exiftool_path=None, exiftool_obj=None):
def __init__(self, filename: str, exiftool_path=None, exiftool_obj=None):
if exiftool_obj is not None:
self.exif = exiftool_obj.get_metadata(filename)
return
Expand All @@ -48,7 +48,7 @@ def __init__(self, filename, exiftool_path=None, exiftool_obj=None):
self.exiftoolPath = None
if not os.path.isfile(filename):
raise IOError("Input path is not a file")
with exiftool.ExifTool(self.exiftoolPath) as exift:
with exiftool.ExifToolHelper() as exift:
self.exif = exift.get_metadata(filename)

def get_all(self):
Expand All @@ -59,10 +59,11 @@ def get_item(self, item, index=None):
""" Get metadata item by Namespace:Parameter"""
val = None
try:
val = self.exif[item]
assert len(self.exif) > 0
val = self.exif[0][item]
if index is not None:
try:
if isinstance(val, unicode):
if isinstance(val, pytz.unicode):
val = val.encode('ascii', 'ignore')
except NameError:
# throws on python 3 where unicode is undefined
Expand All @@ -83,7 +84,7 @@ def size(self, item):
"""get the size (length) of a metadata item"""
val = self.get_item(item)
try:
if isinstance(val, unicode):
if isinstance(val, pytz.unicode):
val = val.encode('ascii', 'ignore')
except NameError:
# throws on python 3 where unicode is undefined
Expand Down Expand Up @@ -132,7 +133,6 @@ def utc_time(self):
if subsec < 0:
negative = -1.0
subsec *= -1.0
subsec = float('0.{}'.format(int(subsec)))
subsec *= negative
ms = subsec * 1e3
utc_time += timedelta(milliseconds=ms)
Expand Down Expand Up @@ -336,7 +336,7 @@ def horizontal_irradiance_valid(self):
return version.parse(version_string) >= version.parse(good_version)

def spectral_irradiance(self):
""" Raw spectral irradiance measured by an irradiance sensor.
""" Raw spectral irradiance measured by an irradiance sensor.
Calibrated to W/m^2/nm using irradiance_scale_factor, but not corrected for angles """
return self.__float_or_zero(self.get_item('XMP:SpectralIrradiance')) * self.irradiance_scale_factor()

Expand Down Expand Up @@ -379,7 +379,7 @@ def auto_calibration_image(self):
self.panel_serial() is not None

def panel_albedo(self):
""" Surface albedo of the active portion of the reflectance panel as calculated by the camera
""" Surface albedo of the active portion of the reflectance panel as calculated by the camera
(usually from the information in the panel QR code) """
albedo = self.get_item('XMP:Albedo')
if albedo is not None:
Expand Down
6 changes: 3 additions & 3 deletions micasense/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ def correct_lens_distortion(meta, image):
ndistortion = meta.size('XMP:PerspectiveDistortion')
distortion_parameters = np.array([float(meta.get_item('XMP:PerspectiveDistortion', i)) for i in range(ndistortion)])
# get the two principal points
pp = np.array(meta.get_item('XMP:PrincipalPoint').split(',')).astype(np.float)
pp = np.array(meta.get_item('XMP:PrincipalPoint').split(',')).astype(float)
# values in pp are in [mm] and need to be rescaled to pixels
focal_plane_x_resolution = float(meta.get_item('EXIF:focal_plane_x_resolution'))
focal_plane_y_resolution = float(meta.get_item('EXIF:focal_plane_y_resolution'))
focal_plane_x_resolution = float(meta.get_item('EXIF:FocalPlaneXResolution'))
focal_plane_y_resolution = float(meta.get_item('EXIF:FocalPlaneYResolution'))

cX = pp[0] * focal_plane_x_resolution
cY = pp[1] * focal_plane_y_resolution
Expand Down
94 changes: 47 additions & 47 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"""

import glob
import os
from pathlib import Path

import pytest

Expand All @@ -35,39 +35,39 @@

@pytest.fixture()
def files_dir():
return os.path.join('data', 'REDEDGE-MX')
return Path(__file__).parent.parent/'data'/'REDEDGE-MX'


@pytest.fixture()
def altum_files_dir():
return os.path.join('data', 'ALTUM')
return Path(__file__).parent.parent/'data'/'ALTUM'


@pytest.fixture()
def ten_band_files_dir():
return os.path.join('data', 'REDEDGE-MX-DUAL')
return Path(__file__).parent.parent/'data'/'REDEDGE-MX-DUAL'


@pytest.fixture()
def panel_rededge_file_list(files_dir):
return glob.glob(os.path.join(files_dir, 'IMG_0001_*.tif'))
def panel_rededge_file_list(files_dir: Path):
return glob.glob(str(files_dir/'IMG_0001_*.tif'))


@pytest.fixture()
def non_panel_rededge_file_list(files_dir):
return glob.glob(os.path.join(files_dir, 'IMG_0020_*.tif'))
def non_panel_rededge_file_list(files_dir: Path):
return glob.glob(str(files_dir/'IMG_0020_*.tif'))


@pytest.fixture()
def bad_file_list(files_dir):
file1 = os.path.join(files_dir, 'IMG_0020_1.tif')
file2 = os.path.join(files_dir, 'IMG_0001_1.tif')
def bad_file_list(files_dir: Path):
file1 = str(files_dir/'IMG_0020_1.tif')
file2 = str(files_dir/'IMG_0001_1.tif')
return [file1, file2]


@pytest.fixture()
def panel_altum_file_list(altum_files_dir):
return glob.glob(os.path.join(altum_files_dir, 'IMG_0000_*.tif'))
return glob.glob(str(altum_files_dir/'IMG_0000_*.tif'))


@pytest.fixture()
Expand All @@ -81,13 +81,13 @@ def non_panel_rededge_capture(non_panel_rededge_file_list):


@pytest.fixture()
def panel_10band_rededge_file_list(ten_band_files_dir):
return glob.glob(os.path.join(ten_band_files_dir, 'IMG_0001_*.tif'))
def panel_10band_rededge_file_list(ten_band_files_dir: Path):
return glob.glob(str(ten_band_files_dir/'IMG_0001_*.tif'))


@pytest.fixture()
def flight_10band_rededge_file_list(ten_band_files_dir):
return glob.glob(os.path.join(ten_band_files_dir, 'IMG_0007_*.tif'))
def flight_10band_rededge_file_list(ten_band_files_dir: Path):
return glob.glob(str(ten_band_files_dir/'IMG_0007_*.tif'))


@pytest.fixture()
Expand All @@ -97,8 +97,8 @@ def panel_altum_capture(panel_altum_file_list):


@pytest.fixture()
def non_panel_altum_file_list(altum_files_dir):
return glob.glob(os.path.join(altum_files_dir, 'IMG_0021_*.tif'))
def non_panel_altum_file_list(altum_files_dir: Path):
return glob.glob(str(altum_files_dir/'IMG_0021_*.tif'))


@pytest.fixture()
Expand All @@ -109,50 +109,50 @@ def non_panel_altum_capture(non_panel_altum_file_list):

@pytest.fixture()
def panel_image_name():
image_path = os.path.join('data', 'REDEDGE-MX')
return os.path.join(image_path, 'IMG_0001_1.tif')
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'
return str(image_path/'IMG_0001_1.tif')


@pytest.fixture()
def panel_image_name_red():
image_path = os.path.join('data', 'REDEDGE-MX')
return os.path.join(image_path, 'IMG_0001_2.tif')
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'
return str(image_path/'IMG_0001_2.tif')


@pytest.fixture()
def flight_image_name():
image_path = os.path.join('data', 'REDEDGE-MX')
return os.path.join(image_path, 'IMG_0020_1.tif')
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'
return str(image_path/'IMG_0020_1.tif')


@pytest.fixture()
def altum_panel_image_name(altum_files_dir):
return os.path.join(altum_files_dir, 'IMG_0000_1.tif')
def altum_panel_image_name(altum_files_dir: Path):
return str(altum_files_dir/'IMG_0000_1.tif')


@pytest.fixture()
def altum_lwir_image_name(altum_files_dir):
return os.path.join(altum_files_dir, 'IMG_0000_6.tif')
def altum_lwir_image_name(altum_files_dir: Path):
return str(altum_files_dir/'IMG_0000_6.tif')


@pytest.fixture()
def altum_flight_image_name(altum_files_dir):
return os.path.join(altum_files_dir, 'IMG_0021_1.tif')
def altum_flight_image_name(altum_files_dir: Path):
return str(altum_files_dir/'IMG_0021_1.tif')


@pytest.fixture()
def img(files_dir):
return image.Image(os.path.join(files_dir, 'IMG_0001_1.tif'))
def img(files_dir: Path):
return image.Image(str(files_dir/'IMG_0001_1.tif'))


@pytest.fixture()
def img2(files_dir):
return image.Image(os.path.join(files_dir, 'IMG_0001_2.tif'))
def img2(files_dir: Path):
return image.Image(str(files_dir/'IMG_0001_2.tif'))


@pytest.fixture()
def panel_altum_file_name(altum_files_dir):
return os.path.join(altum_files_dir, 'IMG_0000_1.tif')
return str(altum_files_dir/'IMG_0000_1.tif')


@pytest.fixture()
Expand All @@ -166,31 +166,31 @@ def altum_flight_image(altum_flight_image_name):


@pytest.fixture()
def non_existant_file_name(altum_files_dir):
return os.path.join(altum_files_dir, 'NOFILE.tif')
def non_existant_file_name(altum_files_dir: Path):
return str(altum_files_dir/'NOFILE.tif')


@pytest.fixture()
def altum_lwir_image(altum_files_dir):
return image.Image(os.path.join(altum_files_dir, 'IMG_0000_6.tif'))
def altum_lwir_image(altum_files_dir: Path):
return image.Image(str(altum_files_dir/'IMG_0000_6.tif'))


@pytest.fixture()
def meta():
image_path = os.path.join('data', 'REDEDGE-MX')
return metadata.Metadata(os.path.join(image_path, 'IMG_0001_1.tif'))
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'/'IMG_0001_1.tif'
return metadata.Metadata(str(image_path))


@pytest.fixture()
def meta_v3():
image_path = os.path.join('data', 'REDEDGE-MX')
return metadata.Metadata(os.path.join(image_path, 'IMG_0020_4.tif'))
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'
return metadata.Metadata(str(image_path/'IMG_0020_4.tif'))


@pytest.fixture()
def meta_bad_exposure():
image_path = os.path.join('data', 'REDEDGE-MX')
return metadata.Metadata(os.path.join(image_path, 'IMG_0020_1.tif'))
image_path = Path(__file__).parent.parent/'data'/'REDEDGE-MX'
return metadata.Metadata(str(image_path/'IMG_0020_1.tif'))


@pytest.fixture()
Expand All @@ -200,8 +200,8 @@ def meta_altum_dls2(altum_flight_image_name):

@pytest.fixture()
def bad_dls2_horiz_irr_image():
image_path = os.path.join('data', 'ALTUM')
return image.Image(os.path.join(image_path, 'IMG_0021_1.tif'))
image_path = Path(__file__).parent.parent/'data'/'ALTUM'
return image.Image(str(image_path/'IMG_0021_1.tif'))


@pytest.fixture()
Expand Down
3 changes: 2 additions & 1 deletion tests/test_imageset.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"""

import os
from pathlib import Path

import pytest

Expand All @@ -33,7 +34,7 @@

@pytest.fixture()
def files_dir():
return os.path.join('data', 'REDEDGE-MX')
return Path(__file__).parent.parent/'data'/'REDEDGE-MX'


progress_val = 0.0
Expand Down

0 comments on commit dfc8ac0

Please sign in to comment.