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

Alternatives to opencv (cv2) #532 [Solved] #853

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 42 additions & 8 deletions alibi_detect/utils/perturbation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from io import BytesIO
from typing import List, Tuple, Union

import cv2
import numpy as np
import skimage as sk
from alibi_detect.utils.data import Bunch
Expand All @@ -14,6 +13,14 @@
from scipy.ndimage.interpolation import map_coordinates
from skimage.filters import gaussian

try:
import cv2
except:
cv2 = None
from scipy.signal import convolve2d
from skimage.transform import AffineTransform, warp
from skimage import img_as_ubyte


def apply_mask(X: np.ndarray,
mask_size: tuple = (4, 4),
Expand Down Expand Up @@ -632,8 +639,17 @@ def disk(radius: float, alias_blur: float = 0.1, dtype=np.float32) -> np.ndarray
aliased_disk = np.array((X ** 2 + Y ** 2) <= radius ** 2, dtype=dtype)
aliased_disk /= np.sum(aliased_disk)

# supersample disk to antialias
return cv2.GaussianBlur(aliased_disk, ksize=ksize, sigmaX=alias_blur)
if cv2 is not None:
# supersample disk to antialias
return cv2.GaussianBlur(aliased_disk, ksize=ksize, sigmaX=alias_blur)

else:
# Create Gaussian kernel
kernel = np.exp(-(X**2 + Y**2) / (2.0 * alias_blur**2))
kernel /= np.sum(kernel)

# Convolve with the aliased disk
return convolve2d(aliased_disk, kernel, mode='same', boundary='wrap')


def defocus_blur(x: np.ndarray, radius: int, alias_blur: float, xrange: tuple = None) -> np.ndarray:
Expand All @@ -658,9 +674,16 @@ def defocus_blur(x: np.ndarray, radius: int, alias_blur: float, xrange: tuple =
x, scale_back = scale_minmax(x, xrange)
kernel = disk(radius=radius, alias_blur=alias_blur)
channels = []
for d in range(3):
channels.append(cv2.filter2D(x[:, :, d], -1, kernel))
x_db = np.array(channels).transpose((1, 2, 0))

if cv2 is not None:
for d in range(3):
channels.append(cv2.filter2D(x[:, :, d], -1, kernel))
x_db = np.array(channels).transpose((1, 2, 0))
else:
for d in range(3):
channels.append(convolve2d(x[:, :, d], kernel, mode='same', boundary='wrap'))
x_db = np.array(channels).transpose((1, 2, 0)).astype(np.float32)

if scale_back:
x_db = x_db * (xrange[1] - xrange[0]) + xrange[0]
if isinstance(xrange, tuple):
Expand Down Expand Up @@ -941,8 +964,19 @@ def elastic_transform(x: np.ndarray, mult_dxdy: float, sigma: float,
[center_square[0] + square_size, center_square[1] - square_size],
center_square - square_size], dtype=np.float32)
pts2 = pts1 + np.random.uniform(-rnd_rng, rnd_rng, size=pts1.shape).astype(np.float32)
M = cv2.getAffineTransform(pts1, pts2)
image = cv2.warpAffine(x, M, shape_size[::-1], borderMode=cv2.BORDER_REFLECT_101)

if cv2 is not None:
M = cv2.getAffineTransform(pts1, pts2)
image = cv2.warpAffine(x, M, shape_size[::-1], borderMode=cv2.BORDER_REFLECT_101)

else:
M = AffineTransform()
M.estimate(pts1, pts2)

image = warp(x, M.inverse, output_shape=shape_size[::-1], mode='reflect')
# image = warp(x, M, output_shape=shape_size[::-1], mode='reflect')
image = img_as_ubyte(image)

dx = (gaussian(np.random.uniform(-1, 1, size=shape_size),
sigma, mode='reflect', truncate=3) * mult_dxdy).astype(np.float32)
dy = (gaussian(np.random.uniform(-1, 1, size=shape_size),
Expand Down
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ def readme():
"pykeops>=2.0.0, <2.2.0",
"torch>=1.7.0, <1.14.0"
],
# https://github.com/SeldonIO/alibi-detect/issues/532
"opencv-python": [
"opencv-python>=3.2.0, <5.0.0"
],
"all": [
"prophet>=1.1.0, <2.0.0",
"tensorflow_probability>=0.8.0, <0.22.0",
"tensorflow>=2.2.0, !=2.6.0, !=2.6.1, <2.14.0", # https://github.com/SeldonIO/alibi-detect/issues/375 and 387
"pykeops>=2.0.0, <2.2.0",
"torch>=1.7.0, <1.14.0"
"opencv-python>=3.2.0, <5.0.0"
],
}

Expand All @@ -53,7 +58,7 @@ def readme():
"numpy>=1.16.2, <2.0.0",
"pandas>=1.0.0, <3.0.0",
"Pillow>=5.4.1, <11.0.0",
"opencv-python>=3.2.0, <5.0.0",
# "opencv-python>=3.2.0, <5.0.0", # Eradicated cv2 (opencv) requirement: https://github.com/SeldonIO/alibi-detect/issues/532
"scipy>=1.3.0, <2.0.0",
'scikit-image>=0.14.2, !=0.17.1, <0.22', # https://github.com/SeldonIO/alibi/issues/215
"scikit-learn>=0.20.2, <2.0.0",
Expand Down