Skip to content

Commit

Permalink
Merge branch 'hotfix/v2.0.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
tayden committed Nov 3, 2020
2 parents bfd4699 + 62c3a32 commit db3fec3
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 12 deletions.
29 changes: 27 additions & 2 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ def _err_callback(path, exception):

def process(self, masker: Masker):
with tqdm(total=len(masker)) as progress:
return masker.process(max_workers=self.max_workers, callback=lambda _: progress.update(),
err_callback=self._err_callback)
return masker(max_workers=self.max_workers,
callback=lambda _: progress.update(),
err_callback=self._err_callback)

def rgb_threshold(self, img_dir: str, out_dir: str, thresholds: List[float] = (1, 1, 0.875),
pixel_buffer: int = 0) -> None:
Expand All @@ -59,6 +60,30 @@ def rgb_threshold(self, img_dir: str, out_dir: str, thresholds: List[float] = (1
"""
self.process(RGBThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer))

def aco_threshold(self, img_dir: str, out_dir: str, thresholds: List[float] = (1, 1, 0.875, 1),
pixel_buffer: int = 0) -> None:
"""Generate masks for glint regions in ACO imagery using Tom Bell's binning algorithm.
Parameters
----------
img_dir
The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg,
and png images in that directory will be processed.
out_dir
The path to send your out image including the file name and type. e.g. "/path/to/mask.png".
out_dir must be a directory if img_dir is specified as a directory.
thresholds
The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). Default is [1, 1, 0.875].
pixel_buffer
The pixel distance to buffer out the mask. Defaults to 0 (off).
Returns
-------
None
Side effects are that the mask is saved to the specified out_dir location.
"""
self.process(RGBThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer))

def p4ms_threshold(self, img_dir: str, out_dir: str, thresholds: List[float] = (0.875, 1, 1, 1, 1),
pixel_buffer: int = 0) -> None:
"""Generate masks for glint regions in multispectral imagery from the DJI camera using Tom Bell's algorithm on
Expand Down
4 changes: 3 additions & 1 deletion core/image_loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Date: 2020-09-18
Description:
"""
import os
import re
from abc import ABC, ABCMeta, abstractmethod
from functools import singledispatchmethod
Expand Down Expand Up @@ -64,7 +65,8 @@ def images(self) -> Iterable[np.ndarray]:
class RGB8BitLoader(SingleFileImageLoader):
@property
def paths(self) -> Iterable[str]:
return list_images(self.image_directory)
# Filter anything smaller than 1kb, since it's probably corrupt
return filter(lambda p: os.stat(p).st_size > (1 << 20), list_images(self.image_directory))

def preprocess_image(self, img: np.ndarray) -> np.ndarray:
return normalize_img(img, bit_depth=8)
Expand Down
20 changes: 15 additions & 5 deletions core/maskers.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,24 @@ def __call__(self, max_workers: int,
err_callback
Optional callback that receives the img_path and an Exception as args after a processing failure.
"""
return self.process(max_workers, callback, err_callback)
if max_workers == 0:
return self.process_unthreaded(callback, err_callback)
else:
return self.process(max_workers, callback, err_callback)

# noinspection SpellCheckingInspection
def process_unthreaded(self, callback: Optional[Callable[[List[str]], None]] = None) -> None:
def process_unthreaded(self, callback: Optional[Callable[[List[str]], None]] = None,
err_callback: Optional[Callable[[List[str], Exception], None]] = None) -> None:
for img, paths in zip(self.image_loader.images, self.image_loader.paths):
self._process_one(img, paths)
if callback is not None:
callback(paths)
try:
self._process_one(img, paths)
if callback is not None:
callback(paths)

except Exception as exc:
if err_callback is not None:
err_callback(paths, exc)
return

def process(self, max_workers: int = os.cpu_count() * 5, callback: Optional[Callable[[List[str]], None]] = None,
err_callback: Optional[Callable[[List[str], Exception], None]] = None) -> None:
Expand Down
2 changes: 1 addition & 1 deletion gui/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
DEFAULT_REDEDGE_THRESH = 1.000
DEFAULT_NIR_THRESH = 1.000
DEFAULT_PIXEL_BUFFER = 0
DEFAULT_MAX_WORKERS = 1
DEFAULT_MAX_WORKERS = 0
2 changes: 1 addition & 1 deletion gui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def img_type(self) -> str:

@property
def max_workers(self) -> int:
return max(self.max_workers_spinbox.value(), 1)
return max(self.max_workers_spinbox.value(), 0)

@property
def mask_method(self) -> str:
Expand Down
4 changes: 2 additions & 2 deletions gui/resources/gui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,13 @@
<item>
<widget class="QSpinBox" name="max_workers_spinbox">
<property name="minimum">
<number>1</number>
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>4</number>
<number>1</number>
</property>
</widget>
</item>
Expand Down

0 comments on commit db3fec3

Please sign in to comment.