Spaces:
Runtime error
Runtime error
""" | |
DeepLabCut Toolbox (deeplabcut.org) | |
© A. & M. Mathis Labs | |
Licensed under GNU Lesser General Public License v3.0 | |
""" | |
import numpy as np | |
import warnings | |
from dlclive.exceptions import DLCLiveWarning | |
try: | |
import skimage | |
SK_IM = True | |
except Exception: | |
SK_IM = False | |
try: | |
import cv2 | |
OPEN_CV = True | |
except Exception: | |
from PIL import Image | |
OPEN_CV = False | |
warnings.warn( | |
"OpenCV is not installed. Using pillow for image processing, which is slower.", | |
DLCLiveWarning, | |
) | |
def convert_to_ubyte(frame): | |
""" Converts an image to unsigned 8-bit integer numpy array. | |
If scikit-image is installed, uses skimage.img_as_ubyte, otherwise, uses a similar custom function. | |
Parameters | |
---------- | |
image : :class:`numpy.ndarray` | |
an image as a numpy array | |
Returns | |
------- | |
:class:`numpy.ndarray` | |
image converted to uint8 | |
""" | |
if SK_IM: | |
return skimage.img_as_ubyte(frame) | |
else: | |
return _img_as_ubyte_np(frame) | |
def resize_frame(frame, resize=None): | |
""" Resizes an image. Uses OpenCV if installed, otherwise, uses pillow | |
Parameters | |
---------- | |
image : :class:`numpy.ndarray` | |
an image as a numpy array | |
""" | |
if (resize is not None) and (resize != 1): | |
if OPEN_CV: | |
new_x = int(frame.shape[0] * resize) | |
new_y = int(frame.shape[1] * resize) | |
return cv2.resize(frame, (new_y, new_x)) | |
else: | |
img = Image.fromarray(frame) | |
img = img.resize((new_y, new_x)) | |
return np.asarray(img) | |
else: | |
return frame | |
def img_to_rgb(frame): | |
""" Convert an image to RGB. Uses OpenCV is installed, otherwise uses pillow. | |
Parameters | |
---------- | |
frame : :class:`numpy.ndarray | |
an image as a numpy array | |
""" | |
if frame.ndim == 2: | |
return gray_to_rgb(frame) | |
elif frame.ndim == 3: | |
return bgr_to_rgb(frame) | |
else: | |
warnings.warn( | |
f"Image has {frame.ndim} dimensions. Must be 2 or 3 dimensions to convert to RGB", | |
DLCLiveWarning, | |
) | |
return frame | |
def gray_to_rgb(frame): | |
""" Convert an image from grayscale to RGB. Uses OpenCV is installed, otherwise uses pillow. | |
Parameters | |
---------- | |
frame : :class:`numpy.ndarray | |
an image as a numpy array | |
""" | |
if OPEN_CV: | |
return cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) | |
else: | |
img = Image.fromarray(frame) | |
img = img.convert("RGB") | |
return np.asarray(img) | |
def bgr_to_rgb(frame): | |
""" Convert an image from BGR to RGB. Uses OpenCV is installed, otherwise uses pillow. | |
Parameters | |
---------- | |
frame : :class:`numpy.ndarray | |
an image as a numpy array | |
""" | |
if OPEN_CV: | |
return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | |
else: | |
img = Image.fromarray(frame) | |
img = img.convert("RGB") | |
return np.asarray(img) | |
def _img_as_ubyte_np(frame): | |
""" Converts an image as a numpy array to unsinged 8-bit integer. | |
As in scikit-image img_as_ubyte, converts negative pixels to 0 and converts range to [0, 255] | |
Parameters | |
---------- | |
image : :class:`numpy.ndarray` | |
an image as a numpy array | |
Returns | |
------- | |
:class:`numpy.ndarray` | |
image converted to uint8 | |
""" | |
frame = np.array(frame) | |
im_type = frame.dtype.type | |
# check if already ubyte | |
if np.issubdtype(im_type, np.uint8): | |
return frame | |
# if floating | |
elif np.issubdtype(im_type, np.floating): | |
if (np.min(frame) < -1) or (np.max(frame) > 1): | |
raise ValueError("Images of type float must be between -1 and 1.") | |
frame *= 255 | |
frame = np.rint(frame) | |
frame = np.clip(frame, 0, 255) | |
return frame.astype(np.uint8) | |
# if integer | |
elif np.issubdtype(im_type, np.integer): | |
im_type_info = np.iinfo(im_type) | |
frame *= 255 / im_type_info.max | |
frame[frame < 0] = 0 | |
return frame.astype(np.uint8) | |
else: | |
raise TypeError( | |
"image of type {} could not be converted to ubyte".format(im_type) | |
) | |
def decode_fourcc(cc): | |
""" | |
Convert float fourcc code from opencv to characters. | |
If decode fails, returns empty string. | |
https://stackoverflow.com/a/49138893 | |
Arguments: | |
cc (float, int): fourcc code from opencv | |
Returns: | |
str: Character format of fourcc code | |
Examples: | |
>>> vid = cv2.VideoCapture('/some/video/path.avi') | |
>>> decode_fourcc(vid.get(cv2.CAP_PROP_FOURCC)) | |
'DIVX' | |
""" | |
try: | |
decoded = "".join([chr((int(cc) >> 8 * i) & 0xFF) for i in range(4)]) | |
except: | |
decoded = "" | |
return decoded | |