1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
#!/usr/bin/env python3
r'''Test of the save_image() and load_image() functions
'''
import sys
import numpy as np
import numpysane as nps
import os
testdir = os.path.dirname(os.path.realpath(__file__))
# I import the LOCAL mrcal since that's what I'm testing
sys.path[:0] = f"{testdir}/..",
import mrcal
import testutils
import tempfile
import atexit
import shutil
workdir = tempfile.mkdtemp()
def cleanup():
global workdir
try:
shutil.rmtree(workdir)
workdir = None
except:
pass
atexit.register(cleanup)
W,H = 133,211
images = dict()
images[8] = np.arange(W*H, dtype=np.uint8).reshape(H,W)
images[8] *= images[8]
images[16] = np.arange(W*H, dtype=np.uint16).reshape(H,W)
images[16] *= images[16]
images[24] = np.arange(W*H*3, dtype=np.uint8).reshape(H,W,3)
images[24] *= images[24]
filename_pattern = f"{workdir}/tst.{{extension}}"
def _check_load(filename, image_ref, what,
should_fail_load = False,
compare_value = True,
extension = None,
**kwargs):
if should_fail_load:
testutils.confirm_raises(lambda: mrcal.load_image(filename, **kwargs),
msg = f"Loading {what} image should fail")
return
try:
image_check = mrcal.load_image(filename, **kwargs)
except Exception as e:
testutils.confirm(False,
msg = f"Error loading {what} image: {e}")
return
testutils.confirm(True,
msg = f"Success loading {what} image")
# print(image_ref.shape)
# print(image_check.shape)
# print(image_ref.dtype)
# print(image_check.dtype)
bpp_load = kwargs.get('bits_per_pixel')
channels_load = kwargs.get('channels')
if bpp_load is not None:
H,W = image_ref.shape[:2]
if bpp_load == 8:
testutils.confirm_equal(image_check.shape, (H,W),
msg = "Shapes match. Loading 8bpp-1channel image")
testutils.confirm_equal(image_check.ndim, 2,
msg = "channels match. Loading 8bpp-1channel image")
testutils.confirm(image_check.dtype == np.uint8,
msg = "dtype match. Loading 8bpp-1channel image")
elif bpp_load == 16:
testutils.confirm_equal(image_check.shape, (H,W),
msg = "Shapes match. Loading 16bpp-1channel image")
testutils.confirm_equal(image_check.ndim, 2,
msg = "channels match. Loading 16bpp-1channel image")
testutils.confirm(image_check.dtype == np.uint16,
msg = "dtype match. Loading 16bpp-1channel image")
elif bpp_load == 24:
testutils.confirm_equal(image_check.shape, (H,W,3),
msg = "Shapes match. Loading 24bpp-3channel image")
testutils.confirm_equal(image_check.ndim, 3,
msg = "channels match. Loading 24bpp-3channel image")
testutils.confirm(image_check.dtype == np.uint8,
msg = "dtype match. Loading 24bpp-3channel image")
if compare_value:
# jpg is approximate
if extension == 'jpg':
eps = 10
percentile = 95
worstcase = False
else:
eps = 1e-6
percentile = None
worstcase = True
if bpp_load == 24 and image_ref.ndim==2:
image_ref = nps.glue( nps.dummy(image_ref,-1),
nps.dummy(image_ref,-1),
nps.dummy(image_ref,-1),
axis = -1)
# signed cast to make approximate comparisons work. Otherwise <0 wraps
# around
testutils.confirm_equal(image_ref.astype(np.int32), image_check.astype(np.int32),
worstcase = worstcase,
eps = eps,
percentile = percentile,
msg = f"load/save match for {what}")
for bpp,extension,what in ( (8, 'png', "8bpp png grayscale"),
(16, 'png', "16bpp png grayscale"),
(24, 'png', "24bpp png bgr"),
(8, 'jpg', "8bpp jpg grayscale"),
(24, 'jpg', "24bpp jpg bgr")):
filename = filename_pattern.format(extension=extension)
image = images[bpp]
try:
mrcal.save_image(filename, image)
except:
testutils.confirm(False,
msg = f"Error saving {what} image")
continue
testutils.confirm(True,
msg = f"Success saving {what} image")
def check_load(**kwargs):
if 'bits_per_pixel' not in kwargs:
_check_load(filename, image,
what,
extension = extension,
**kwargs)
else:
_check_load(filename, image,
f"{what} (loading as {kwargs['bits_per_pixel']}bpp)",
extension = extension,
**kwargs)
check_load()
if bpp == 8:
check_load(bits_per_pixel = 16,
channels = 1,
should_fail_load = True)
check_load(bits_per_pixel = 24,
channels = 3)
if bpp == 16:
check_load(bits_per_pixel = 8,
channels = 1,
# values won't match: this path equalizes
compare_value = False)
check_load(bits_per_pixel = 24,
channels = 3,
should_fail_load = True)
if bpp == 24:
check_load(bits_per_pixel = 8,
channels = 1,
# values won't match: colors are collapsed
compare_value = False)
check_load(bits_per_pixel = 16,
channels = 1,
should_fail_load = True)
testutils.finish()
|