Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tested code for for python > 3.9 and numpy >= 2.0 #864

Open
wants to merge 69 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
d39cc7d
Changed np.bool to bool
Apr 13, 2023
418f22d
Replaced all occurrences of np.bool to np.bool_ and np.complex to np.…
u7122029 Jul 26, 2023
a24a221
Descriptive commit message about the changes
Sep 18, 2024
f76a478
Merge pull request #1 from erjel/numpy-types-fix
erjel Oct 25, 2024
4a36102
bugfix: cval is marked as depreciated but alternative is unused.
erjel Oct 25, 2024
33cd223
Merge pull request #2 from erjel/fix_pad_cval
erjel Oct 25, 2024
1bb0bae
dep: opencv 4 introduces error in tests
erjel Oct 27, 2024
d68eb33
Merge pull request #3 from erjel/shape_mismatch
erjel Oct 27, 2024
64e40a6
bugfix: imagecorrupt is ntests are not compatible with skimage > 0.18…
erjel Nov 9, 2024
0901b80
failing tests: Constrain numpy version to fix filing tests; 4 failure…
erjel Nov 10, 2024
b2644bf
bugfix: Further constrain scikit-image to run without test failures
erjel Nov 10, 2024
c7ad467
rf: Make imagecorruptions a hard requirement; depends on opencv-python
erjel Nov 10, 2024
4f354cc
rf: Define development requirements in setup.py
erjel Nov 10, 2024
8189b93
fix: Unable to test on python versions < 3.6; don't claim support
erjel Nov 10, 2024
a2e38f4
Testrun latest changes in CI (#4)
erjel Nov 10, 2024
dda12c8
rf: depreciate python 3.6
erjel Nov 10, 2024
1f6cc17
Merge branch 'depreciate_py36' into test
erjel Nov 10, 2024
c2127fd
build: Relax numpy requirements until tests fail
erjel Nov 10, 2024
daae277
tests: Relax test condition for unlucky seed choice
erjel Nov 11, 2024
fa1fbaa
fixed np.bool in this codebase, but need to relax scikit-image depend…
erjel Nov 11, 2024
e123624
rf: numpy 1.20 introduces numpy.typing; pillow tests for existence of…
erjel Nov 27, 2024
a1c65e4
dep: Numpy 1.22 works without errors
erjel Nov 27, 2024
3b37436
bugfix: Numpy 1.23 creates zero-sized arrays which opencv 3 cannot ha…
erjel Nov 27, 2024
0e38f41
dep: relax numpy version to 1.23
erjel Nov 27, 2024
8bc113e
merge
erjel Nov 28, 2024
04d7581
bugfix: NameError: name 'bool_' is not defined
erjel Nov 28, 2024
b788387
Bug: Inconsistent behavior on left and right boundary
erjel Dec 2, 2024
265bf1b
fix failing tests: Bugfix in skimage 0.18.0 mitigates inconsistent be…
erjel Dec 3, 2024
509c162
dep: No numpy restrictions needed for python 3.8
erjel Dec 3, 2024
467b660
bugfix: Different behavior for scikit-image's transform.warp
erjel Dec 3, 2024
f9a253b
Add overflow test and delete cval test
erjel Dec 4, 2024
116c8fd
bugfix: Use new imagecorruptions version which fixes determinism for …
erjel Dec 6, 2024
905f900
bugfix: Add support for scikit-image 0.20
erjel Dec 6, 2024
1de8890
deps: Unlimited scikit-image support (for python 3.8)
erjel Dec 6, 2024
497223d
Check tests on macos-latest (14)
erjel Dec 12, 2024
8872e2e
Merge pull request #5 from erjel/relax_numpy
erjel Dec 13, 2024
47e4116
bugfix: Warning does not match description. Don't care about warning …
erjel Dec 13, 2024
6f584cd
bugfix: Include numpy 1.26 to list of supported versions
erjel Dec 13, 2024
dedb50a
restrict numpy version until opencv4 is supported
erjel Dec 13, 2024
75e96ad
tests: Delete differnet test routines for float128 systems
erjel Dec 16, 2024
e1ca005
bugfix: Make sure random.seed receives int tpyes
erjel Dec 16, 2024
67d2a0b
bugfix: Dont restrict warning messages
erjel Dec 16, 2024
ef3c4fb
dep: Support for recent python versions added
erjel Dec 16, 2024
13af84e
bugfix: Python versions as strings
erjel Dec 16, 2024
09475fc
Use backward compatible imagecorruptions
erjel Dec 16, 2024
4b21820
dep: Use updated imagecorruptions version
erjel Dec 16, 2024
9d14b3b
bugfix: use different imagecorruptsion
erjel Dec 17, 2024
90127ce
dep: Yet another imagecorruptions version
erjel Dec 17, 2024
6fc3ed5
bugfix
erjel Dec 17, 2024
4132640
dep: Use latest opencv and skip windows tests for now
erjel Dec 17, 2024
4c17ce2
:Merge remote-tracking branch 'numpy2-fix/support-numpy2.0' into numpy2
erjel Dec 17, 2024
feeb2d6
str != np.float16
erjel Dec 17, 2024
46469fb
bugfix: division by max of base array casts to float64
erjel Dec 17, 2024
d914b61
bugfix: * operation changes output dtype
erjel Dec 18, 2024
478da1a
test: fix type
erjel Dec 18, 2024
573b078
bugfix: Make sure arrays have correct type and are C-continous
erjel Dec 18, 2024
6c446fa
bugfix: Fix numpy 2 depreciations
erjel Dec 18, 2024
1161492
bugfix
erjel Dec 18, 2024
16ebe7a
bugfix: use correct cval dtype
erjel Dec 18, 2024
34b0daf
bugfix: Numpy 2 added overflow error
erjel Dec 18, 2024
fc77d5d
test: Fix inf for np.float16
erjel Dec 18, 2024
b6a272f
test: fix failing tests due to numpy 2
erjel Dec 18, 2024
cb3ad99
deps: Support numpy 2
erjel Dec 18, 2024
056e27e
ci: skip windows test for now
erjel Dec 18, 2024
1a7b340
doctests: Quick fix tests
erjel Dec 18, 2024
a71fb00
ci: Decided not to support depreciated BatchLoader on Windows
erjel Dec 18, 2024
4c6a9bd
Merge pull request #12 from erjel/fix_windows
erjel Dec 18, 2024
32ee0b8
Merge pull request #11 from erjel/numpy2
erjel Dec 18, 2024
83222c2
Merge pull request #13 from erjel/opencv4
erjel Dec 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 16 additions & 25 deletions .github/workflows/test_pull_requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,30 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
# see supported versions at
# https://raw.githubusercontent.com/actions/python-versions/master/versions-manifest.json
python-version: [2.7, 3.5, 3.6, 3.7, 3.8]
# test only 2.7 and the latest 3.x on mac
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
# test only the latest 3.x on mac
# test only the latest 3.x on windows
exclude:
- os: macos-latest
python-version: 3.5
python-version: '3.7'
- os: macos-latest
python-version: 3.6
python-version: '3.8'
- os: macos-latest
python-version: 3.7
python-version: '3.9'
- os: macos-latest
python-version: '3.10'
- os: macos-latest
python-version: '3.11'
- os: windows-latest
python-version: '3.7'
- os: windows-latest
python-version: 2.7 # causes a Shapely install error
python-version: '3.8'
- os: windows-latest
python-version: 3.5
python-version: '3.9'
- os: windows-latest
python-version: 3.6
python-version: '3.10'
- os: windows-latest
python-version: 3.7
python-version: '3.11'
env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python-version }}
Expand Down Expand Up @@ -103,27 +109,12 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-

# ----------------
# Install dependencies
# ----------------
- name: Install dependencies
run: |
pip install -r requirements.txt

- name: Install test dependencies
run: |
pip install --upgrade -r test/requirements.txt

- name: Install further test tools
run: |
pip install coverage pytest-cov flake8

# ----------------
# Install library
# ----------------
- name: Install library
run: |
pip install .
pip install .[dev]

# ----------------
# Run checks and tests
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ It converts a set of input images into a new, much larger set of slightly altere
4. [Recent Changes](#recent_changes)
5. [Example Images](#example_images)
6. [Code Examples](#code_examples)
7. [Citation](#citation)
7. [Development](#development)
8. [Citation](#citation)


<a name="features"/>
Expand Down Expand Up @@ -121,7 +122,7 @@ It converts a set of input images into a new, much larger set of slightly altere

## Installation

The library supports python 2.7 and 3.4+.
The library supports python 3.7+.

### Installation: Anaconda

Expand Down Expand Up @@ -1179,6 +1180,20 @@ aug = iaa.WithChannels(
images_aug = aug(images=images)
```

<a name="development"/>

## Development

To install this packages with all development requirments, clone this repository, and run
```
pip install -e .[dev]
```

You can run the tests locally via
```
./test/run_tests.sh
```


<a name="citation"/>

Expand Down
2 changes: 1 addition & 1 deletion imgaug/augmentables/polys.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ def extract_from_image(self, image):
rr_face, cc_face = skimage.draw.polygon(
yy_mask, xx_mask, shape=(height_mask, width_mask))

mask = np.zeros((height_mask, width_mask), dtype=np.bool)
mask = np.zeros((height_mask, width_mask), dtype=bool)
mask[rr_face, cc_face] = True

if image.ndim == 3:
Expand Down
6 changes: 4 additions & 2 deletions imgaug/augmenters/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def _add_scalar_to_uint8_(image, value):
return cv2.add(image, value, dst=image, dtype=cv2.CV_8U)

input_shape = image.shape
image = image.ravel()
image = image.reshape(-1, 1)
values = np.array(value)
if not is_channelwise:
values = np.broadcast_to(values, image.shape)
Expand Down Expand Up @@ -1442,14 +1442,16 @@ def _invert_uint8_lut_pregenerated_(arr, min_value, max_value, threshold,
# Added in 0.5.0.
def _invert_uint8_subtract_(arr, max_value):
# seems to work with arr.base.shape[0] > 1
if arr.size == 0:
return arr
if arr.base is not None and arr.base.shape[0] == 1:
arr = np.copy(arr)
if not arr.flags["C_CONTIGUOUS"]:
arr = np.ascontiguousarray(arr)

input_shape = arr.shape
if len(input_shape) > 2 and input_shape[-1] > 1:
arr = arr.ravel()
arr = arr.reshape(-1, 1)
# This also supports a mask, which would help for thresholded invert, but
# it seems that all non-masked components are set to zero in the output
# array. Tackling this issue seems to rather require more time than just
Expand Down
22 changes: 16 additions & 6 deletions imgaug/augmenters/geometric.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ def _warp_affine_arr_skimage(arr, matrix, cval, mode, order, output_shape):
if input_dtype == iadt._BOOL_DTYPE and order != 0:
arr = arr.astype(np.float32)

if input_dtype == np.float16 and order == 0:
arr = arr.astype(np.float32)

image_warped = tf.warp(
arr,
np.linalg.inv(matrix),
Expand Down Expand Up @@ -3204,19 +3207,26 @@ def _augment_images_by_samples(self, images, samples):
if image.dtype.kind == "b":
image = image.astype(np.float64)

if image.dtype == np.float16 and samples.order[i] == 0:
image = image.astype(np.float32)

cval = samples.get_clipped_cval(i, image.dtype)
image_warped = tf.warp(
image,
transformer,
order=samples.order[i],
mode=samples.mode[i],
cval=samples.get_clipped_cval(i, image.dtype),
cval=cval,
preserve_range=True,
output_shape=images[i].shape
)

if input_dtype.kind == "b":
image_warped = image_warped > 0.5
else:
# fill skimage.transform.warp output nan values with cval
image_warped = np.where(np.isnan(image_warped), cval.astype(input_dtype), image_warped)

# warp seems to change everything to float64, including
# uint8, making this necessary
image_warped = iadt.restore_dtypes_(
Expand Down Expand Up @@ -4789,7 +4799,7 @@ def _map_coordinates(self, image, dx, dy, order=1, cval=0, mode="constant"):
result = np.empty_like(image)

for c in sm.xrange(image.shape[2]):
remapped_flat = ndimage.interpolation.map_coordinates(
remapped_flat = ndimage.map_coordinates(
image[..., c],
(y_shifted.flatten(), x_shifted.flatten()),
order=order,
Expand Down Expand Up @@ -4878,7 +4888,6 @@ def generate(self, shapes, alphas, sigmas, random_state):
# somewhere by 2. It is fastes to multiply the (fewer) alphas, which
# we will have to multiply the shift maps with anyways.
alphas *= 2

# Configuration for each chunk.
# switch dx / dy, flip dx lr, flip dx ud, flip dy lr, flip dy ud
switch = [False, True]
Expand Down Expand Up @@ -4948,9 +4957,8 @@ def _flip(cls, dx, dy, flips):
# Added in 0.5.0.
@classmethod
def _mul_alpha(cls, dx, dy, alpha):
# performance drops for cv2.multiply here
dx = dx * alpha
dy = dy * alpha
dx = (dx * alpha).astype(dx.dtype)
dy = (dy * alpha).astype(dy.dtype)
return dx, dy

# Added in 0.5.0.
Expand All @@ -4961,6 +4969,8 @@ def _smoothen_(cls, dx, dy, sigma):
dy = blur_lib.blur_gaussian_(dy, sigma)
else:
ksize = int(round(2*sigma))
dx = np.ascontiguousarray(dx)
dy = np.ascontiguousarray(dy)
dx = cv2.blur(dx, (ksize, ksize), dst=dx)
dy = cv2.blur(dy, (ksize, ksize), dst=dy)
return dx, dy
Expand Down
20 changes: 17 additions & 3 deletions imgaug/augmenters/imgcorruptlike.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@
"""
from __future__ import print_function, division, absolute_import

import functools
import warnings

import six.moves as sm
import numpy as np
import skimage.filters
import skimage

import imgaug as ia
from ..imgaug import _numbajit
Expand All @@ -93,6 +95,8 @@
"of the package."
)

SK_VERSION = {k:int(v) for k,v in zip(['major', 'minor'], skimage.__version__.split('.')[:2])}


# Added in 0.4.0.
def _clipped_zoom_no_scipy_warning(img, zoom_factor):
Expand Down Expand Up @@ -353,7 +357,12 @@ def apply_impulse_noise(x, severity=1, seed=None):
Corrupted image.

"""
return _call_imgcorrupt_func("impulse_noise", seed, False, x, severity)
return functools.partial(
_call_imgcorrupt_func,
"impulse_noise",
seed,
False,
)(x, severity, seed)


def apply_speckle_noise(x, severity=1, seed=None):
Expand Down Expand Up @@ -473,9 +482,14 @@ def _apply_glass_blur_imgaug(x, severity=1):

sigma, max_delta, iterations = c

if SK_VERSION['major'] >= 0 and SK_VERSION['minor'] >= 19:
kwargs = {'channel_axis': -1}
else: # pre scikit-image 0.19
kwargs = {'multichannel': True}

x = (
skimage.filters.gaussian(
np.array(x) / 255., sigma=sigma, multichannel=True
np.array(x) / 255., sigma=sigma, **kwargs
) * 255
).astype(np.uint)
x_shape = x.shape
Expand All @@ -496,7 +510,7 @@ def _apply_glass_blur_imgaug(x, severity=1):
)

return np.clip(
skimage.filters.gaussian(x / 255., sigma=sigma, multichannel=True),
skimage.filters.gaussian(x / 255., sigma=sigma, **kwargs),
0, 1
) * 255

Expand Down
2 changes: 1 addition & 1 deletion imgaug/augmenters/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -3384,7 +3384,7 @@ def _get_augmenter_active(self, nb_rows, random_state):
# pylint: disable=invalid-name
nn = self._get_n(nb_rows, random_state)
nn = [min(n, len(self)) for n in nn]
augmenter_active = np.zeros((nb_rows, len(self)), dtype=np.bool)
augmenter_active = np.zeros((nb_rows, len(self)), dtype=bool)
for row_idx, n_true in enumerate(nn):
if n_true > 0:
augmenter_active[row_idx, 0:n_true] = 1
Expand Down
14 changes: 7 additions & 7 deletions imgaug/imgaug.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
# to check if a dtype instance is among these dtypes, use e.g.
# `dtype.type in NP_FLOAT_TYPES` do not just use `dtype in NP_FLOAT_TYPES` as
# that would fail
NP_FLOAT_TYPES = set(np.sctypes["float"])
NP_INT_TYPES = set(np.sctypes["int"])
NP_UINT_TYPES = set(np.sctypes["uint"])
NP_FLOAT_TYPES = set([np.float16, np.float32, np.float64])
NP_INT_TYPES = set([np.int8, np.int16, np.int32, np.int64])
NP_UINT_TYPES = set([np.uint8, np.uint16, np.uint32, np.uint64])

IMSHOW_BACKEND_DEFAULT = "matplotlib"

Expand Down Expand Up @@ -697,13 +697,13 @@ def angle_between_vectors(v1, v2):

Examples
--------
>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([0, 1, 0]))
>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([0, 1, 0])).item()
1.570796...

>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([1, 0, 0]))
>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([1, 0, 0])).item()
0.0

>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([-1, 0, 0]))
>>> angle_between_vectors(np.float32([1, 0, 0]), np.float32([-1, 0, 0])).item()
3.141592...

"""
Expand Down Expand Up @@ -1297,7 +1297,7 @@ def pool(arr, block_size, func, pad_mode="constant", pad_cval=0,
input_dtype = arr.dtype

arr_reduced = skimage.measure.block_reduce(arr, tuple(block_size), func,
cval=cval)
cval=pad_cval)
if preserve_dtype and arr_reduced.dtype.name != input_dtype.name:
arr_reduced = arr_reduced.astype(input_dtype)
return arr_reduced
Expand Down
4 changes: 2 additions & 2 deletions imgaug/multicore.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ def __init__(self, load_batch_func, queue_size=50, nb_workers=1,
worker = multiprocessing.Process(
target=self._load_batches,
args=(load_batch_func, self._queue_internal,
self.join_signal, seeds[i])
self.join_signal, int(seeds[i]))
)
worker.daemon = True
worker.start()
Expand Down Expand Up @@ -828,7 +828,7 @@ def __init__(self, batch_loader, augseq, queue_size=50, nb_workers="auto"):
for i in range(nb_workers):
worker = multiprocessing.Process(
target=self._augment_images_worker,
args=(augseq, self.queue_source, self.queue_result, seeds[i])
args=(augseq, self.queue_source, self.queue_result, int(seeds[i]))
)
worker.daemon = True
worker.start()
Expand Down
6 changes: 3 additions & 3 deletions imgaug/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ class Deterministic(StochasticParameter):
--------
>>> import imgaug.parameters as iap
>>> param = iap.Deterministic(10)
>>> param.draw_sample()
>>> param.draw_sample().item()
10

Will always sample the value 10.
Expand Down Expand Up @@ -2588,7 +2588,7 @@ def _draw_samples(self, size, random_state):
# result = np.float_power(samples, exponents)
# TODO why was float32 type here replaced with complex number
# formulation?
result = np.power(samples.astype(np.complex), exponents).real
result = np.power(samples.astype(np.complex128), exponents).real
if result.dtype != samples_dtype:
result = result.astype(samples_dtype)

Expand Down Expand Up @@ -3558,7 +3558,7 @@ def _draw_samples_hw(self, height, width, random_state):
wn = wn.astype(np.float32)

# equivalent but slightly faster then:
# wn_freqs_mul = np.zeros(treal.shape, dtype=np.complex)
# wn_freqs_mul = np.zeros(treal.shape, dtype=np.complex128)
# wn_freqs_mul.real = wn[0]
# wn_freqs_mul.imag = wn[1]
# wn_inv = np.fft.ifft2(wn_freqs_mul).real
Expand Down
15 changes: 0 additions & 15 deletions requirements.txt

This file was deleted.

Loading