Update FFC files
This commit is contained in:
@@ -238,7 +238,7 @@ class FFCFrameProcessor:
|
||||
"""Flat-field correction with offline weight-map calibration and fast online correction."""
|
||||
|
||||
def __init__(self, blur_kernel=151, blur_sigma=0.0, epsilon=1e-6, masked_outside=True):
|
||||
self.blur_kernel = ensure_odd(blur_kernel)
|
||||
self.blur_kernel = self.ensure_odd(blur_kernel)
|
||||
self.blur_sigma = float(blur_sigma)
|
||||
self.epsilon = float(epsilon)
|
||||
self.masked_outside = bool(masked_outside)
|
||||
@@ -252,8 +252,8 @@ class FFCFrameProcessor:
|
||||
self._roi_bbox = None
|
||||
|
||||
def calibrate(self, reference_image, roi_mask=None):
|
||||
gray = to_gray_float32(reference_image)
|
||||
roi_mask = normalize_mask(roi_mask, gray.shape)
|
||||
gray = self.to_gray_float32(reference_image)
|
||||
roi_mask = self.normalize_mask(roi_mask, gray.shape)
|
||||
active = roi_mask > 0
|
||||
if not np.any(active):
|
||||
raise ValueError("ROI mask is empty; cannot calibrate FFC.")
|
||||
@@ -308,7 +308,7 @@ class FFCFrameProcessor:
|
||||
cv2.convertScaleAbs(self._multiplied_buffer, dst=dst_view, alpha=1.0, beta=0.0)
|
||||
return self._output_buffer
|
||||
|
||||
corrected = saturate_to_dtype(self._multiplied_buffer, image.dtype)
|
||||
corrected = self.saturate_to_dtype(self._multiplied_buffer, image.dtype)
|
||||
dst_view[...] = corrected
|
||||
return self._output_buffer
|
||||
|
||||
@@ -379,33 +379,33 @@ class FFCFrameProcessor:
|
||||
x1, y1, x2, y2 = self._roi_bbox
|
||||
self._multiplied_buffer = np.empty((y2 - y1, x2 - x1), dtype=np.float32)
|
||||
|
||||
@staticmethod
|
||||
def ensure_odd(value, minimum=3):
|
||||
value = max(int(value), int(minimum))
|
||||
return value if value % 2 == 1 else value + 1
|
||||
|
||||
def ensure_odd(value, minimum=3):
|
||||
value = max(int(value), int(minimum))
|
||||
return value if value % 2 == 1 else value + 1
|
||||
@staticmethod
|
||||
def to_gray_float32(image):
|
||||
if image.ndim == 2:
|
||||
gray = image
|
||||
elif image.ndim == 3:
|
||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
else:
|
||||
raise ValueError("image must have shape HxW or HxWxC")
|
||||
return gray.astype(np.float32, copy=False)
|
||||
|
||||
@staticmethod
|
||||
def normalize_mask(mask, shape):
|
||||
if mask is None:
|
||||
return np.ones(shape, dtype=np.uint8) * 255
|
||||
mask = np.asarray(mask)
|
||||
if mask.shape[:2] != shape:
|
||||
mask = cv2.resize(mask, (shape[1], shape[0]), interpolation=cv2.INTER_NEAREST)
|
||||
return np.where(mask > 0, 255, 0).astype(np.uint8)
|
||||
|
||||
def to_gray_float32(image):
|
||||
if image.ndim == 2:
|
||||
gray = image
|
||||
elif image.ndim == 3:
|
||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
else:
|
||||
raise ValueError("image must have shape HxW or HxWxC")
|
||||
return gray.astype(np.float32, copy=False)
|
||||
|
||||
|
||||
def normalize_mask(mask, shape):
|
||||
if mask is None:
|
||||
return np.ones(shape, dtype=np.uint8) * 255
|
||||
mask = np.asarray(mask)
|
||||
if mask.shape[:2] != shape:
|
||||
mask = cv2.resize(mask, (shape[1], shape[0]), interpolation=cv2.INTER_NEAREST)
|
||||
return np.where(mask > 0, 255, 0).astype(np.uint8)
|
||||
|
||||
|
||||
def saturate_to_dtype(values, dtype):
|
||||
if np.issubdtype(dtype, np.integer):
|
||||
info = np.iinfo(dtype)
|
||||
return np.clip(values, info.min, info.max).astype(dtype)
|
||||
return values.astype(dtype, copy=False)
|
||||
@staticmethod
|
||||
def saturate_to_dtype(values, dtype):
|
||||
if np.issubdtype(dtype, np.integer):
|
||||
info = np.iinfo(dtype)
|
||||
return np.clip(values, info.min, info.max).astype(dtype)
|
||||
return values.astype(dtype, copy=False)
|
||||
|
||||
Reference in New Issue
Block a user