|
|
|
@ -15,10 +15,8 @@ |
|
|
|
|
import cv2 |
|
|
|
|
import numpy as np |
|
|
|
|
import copy |
|
|
|
|
import operator |
|
|
|
|
import shapely.ops |
|
|
|
|
from shapely.geometry import Polygon, MultiPolygon, GeometryCollection |
|
|
|
|
from functools import reduce |
|
|
|
|
from sklearn.decomposition import PCA |
|
|
|
|
from sklearn.linear_model import LinearRegression |
|
|
|
|
from skimage import exposure |
|
|
|
@ -383,18 +381,19 @@ def resize_rle(rle, im_h, im_w, im_scale_x, im_scale_y, interp): |
|
|
|
|
return rle |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_uint8(im): |
|
|
|
|
def to_uint8(im, is_linear=False): |
|
|
|
|
""" Convert raster to uint8. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
im (np.ndarray): The image. |
|
|
|
|
is_linear (bool, optional): Use 2% linear stretch or not. Default is False. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
np.ndarray: Image on uint8. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
# 2% linear stretch |
|
|
|
|
def _two_percentLinear(image, max_out=255, min_out=0): |
|
|
|
|
def _two_percent_linear(image, max_out=255, min_out=0): |
|
|
|
|
def _gray_process(gray, maxout=max_out, minout=min_out): |
|
|
|
|
# get the corresponding gray level at 98% histogram |
|
|
|
|
high_value = np.percentile(gray, 98) |
|
|
|
@ -402,7 +401,7 @@ def to_uint8(im): |
|
|
|
|
truncated_gray = np.clip(gray, a_min=low_value, a_max=high_value) |
|
|
|
|
processed_gray = ((truncated_gray - low_value) / (high_value - low_value)) * \ |
|
|
|
|
(maxout - minout) |
|
|
|
|
return processed_gray |
|
|
|
|
return np.uint8(processed_gray) |
|
|
|
|
|
|
|
|
|
if len(image.shape) == 3: |
|
|
|
|
processes = [] |
|
|
|
@ -414,52 +413,28 @@ def to_uint8(im): |
|
|
|
|
return np.uint8(result) |
|
|
|
|
|
|
|
|
|
# simple image standardization |
|
|
|
|
def _sample_norm(image, NUMS=65536): |
|
|
|
|
def _sample_norm(image): |
|
|
|
|
stretches = [] |
|
|
|
|
if len(image.shape) == 3: |
|
|
|
|
for b in range(image.shape[-1]): |
|
|
|
|
stretched = _stretch(image[:, :, b], NUMS) |
|
|
|
|
stretched /= float(NUMS) |
|
|
|
|
stretched = exposure.equalize_hist(image[:, :, b]) |
|
|
|
|
stretched /= float(np.max(stretched)) |
|
|
|
|
stretches.append(stretched) |
|
|
|
|
stretched_img = np.stack(stretches, axis=2) |
|
|
|
|
else: # if len(image.shape) == 2 |
|
|
|
|
stretched_img = _stretch(image, NUMS) |
|
|
|
|
stretched_img = exposure.equalize_hist(image) |
|
|
|
|
return np.uint8(stretched_img * 255) |
|
|
|
|
|
|
|
|
|
# histogram equalization |
|
|
|
|
def _stretch(ima, NUMS): |
|
|
|
|
hist = _histogram(ima, NUMS) |
|
|
|
|
lut = [] |
|
|
|
|
for bt in range(0, len(hist), NUMS): |
|
|
|
|
# step size |
|
|
|
|
step = reduce(operator.add, hist[bt:bt + NUMS]) / (NUMS - 1) |
|
|
|
|
# create balanced lookup table |
|
|
|
|
n = 0 |
|
|
|
|
for i in range(NUMS): |
|
|
|
|
lut.append(n / step) |
|
|
|
|
n += hist[i + bt] |
|
|
|
|
np.take(lut, ima, out=ima) |
|
|
|
|
return ima |
|
|
|
|
|
|
|
|
|
# calculate histogram |
|
|
|
|
def _histogram(ima, NUMS): |
|
|
|
|
bins = list(range(0, NUMS)) |
|
|
|
|
flat = ima.flat |
|
|
|
|
n = np.searchsorted(np.sort(flat), bins) |
|
|
|
|
n = np.concatenate([n, [len(flat)]]) |
|
|
|
|
hist = n[1:] - n[:-1] |
|
|
|
|
return hist |
|
|
|
|
|
|
|
|
|
dtype = im.dtype.name |
|
|
|
|
dtypes = ["uint8", "uint16", "float32"] |
|
|
|
|
dtypes = ["uint8", "uint16", "uint32", "float32"] |
|
|
|
|
if dtype not in dtypes: |
|
|
|
|
raise ValueError(f"'dtype' must be uint8/uint16/float32, not {dtype}.") |
|
|
|
|
if dtype == "uint8": |
|
|
|
|
return im |
|
|
|
|
else: |
|
|
|
|
if dtype == "float32": |
|
|
|
|
im = _sample_norm(im) |
|
|
|
|
return _two_percentLinear(im) |
|
|
|
|
raise ValueError( |
|
|
|
|
f"'dtype' must be uint8/uint16/uint32/float32, not {dtype}.") |
|
|
|
|
if dtype != "uint8": |
|
|
|
|
im = _sample_norm(im) |
|
|
|
|
if is_linear: |
|
|
|
|
im = _two_percent_linear(im) |
|
|
|
|
return im |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_intensity(im): |
|
|
|
|