From 5d52c0e5b1ac6f8c492cc4d1d908dc3d1fccbe17 Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 12:57:40 -0700 Subject: [PATCH 1/7] Unify destination handling --- src/boilercv/data/sets.py | 8 +++--- src/boilercv/manual/binarize.py | 43 +++++++++++++++---------------- src/boilercv/manual/convert.py | 2 ++ src/boilercv/manual/decompress.py | 24 ++++++++--------- src/boilercv/stages/contours.py | 6 ++--- 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/src/boilercv/data/sets.py b/src/boilercv/data/sets.py index 2ff32d81..e7999064 100644 --- a/src/boilercv/data/sets.py +++ b/src/boilercv/data/sets.py @@ -37,7 +37,9 @@ def get_dataset(name: str, num_frames: int = 0, frame: slice = ALL_FRAMES) -> DS roi = PARAMS.paths.rois / f"{name}.nc" with xr.open_dataset(source) as ds, xr.open_dataset(roi) as roi_ds: if not unc_source.exists(): - xr.Dataset({VIDEO: ds[VIDEO]}).to_netcdf(path=unc_source) + xr.Dataset({VIDEO: ds[VIDEO], HEADER: ds[HEADER]}).to_netcdf( + path=unc_source + ) return xr.Dataset( { VIDEO: unpack(ds[VIDEO].sel(frame=frame)), @@ -47,7 +49,7 @@ def get_dataset(name: str, num_frames: int = 0, frame: slice = ALL_FRAMES) -> DS ) -def get_large_dataset(video: str) -> DS: +def get_large_dataset(name: str) -> DS: """Load a large video dataset.""" - with xr.open_dataset(LOCAL_PATHS.large_sources / f"{video}.nc") as ds: + with xr.open_dataset(LOCAL_PATHS.large_sources / f"{name}.nc") as ds: return ds diff --git a/src/boilercv/manual/binarize.py b/src/boilercv/manual/binarize.py index fdc42561..cbdb26be 100644 --- a/src/boilercv/manual/binarize.py +++ b/src/boilercv/manual/binarize.py @@ -13,30 +13,29 @@ def main(): + logger.info("start binarize") for source in get_sorted_paths(LOCAL_PATHS.large_sources): - try: - loop(source) - except Exception: - logger.exception(source.stem) + destination = PARAMS.paths.sources / f"{source.stem}.nc" + if destination.exists(): continue - - -def loop(source): - with xr.open_dataset(source) as ds: - video = ds[VIDEO] - maximum = video.max(FRAME) - flooded: DA = apply_to_img_da(flood, maximum) - roi = apply_to_img_da(get_roi, scale_bool(flooded)) - masked: DA = apply_to_img_da(apply_mask, video, scale_bool(roi), vectorize=True) - binarized: DA = apply_to_img_da(binarize, masked, vectorize=True) - ds[VIDEO] = pack(binarized) - ds.to_netcdf( - path=PARAMS.paths.sources / source.name, - encoding={VIDEO: {"zlib": True}}, - ) - ds[ROI] = roi - ds = ds.drop_vars(VIDEO) - ds.to_netcdf(path=PARAMS.paths.rois / source.name) + with xr.open_dataset(source) as ds: + video = ds[VIDEO] + maximum = video.max(FRAME) + flooded: DA = apply_to_img_da(flood, maximum) + roi: DA = apply_to_img_da(get_roi, scale_bool(flooded)) + masked: DA = apply_to_img_da( + apply_mask, video, scale_bool(roi), vectorize=True + ) + binarized: DA = apply_to_img_da(binarize, masked, vectorize=True) + ds[VIDEO] = pack(binarized) + ds.to_netcdf( + path=PARAMS.paths.sources / source.name, + encoding={VIDEO: {"zlib": True}}, + ) + ds[ROI] = roi + ds = ds.drop_vars(VIDEO) + ds.to_netcdf(path=PARAMS.paths.rois / source.name) + logger.info("finish binarize") if __name__ == "__main__": diff --git a/src/boilercv/manual/convert.py b/src/boilercv/manual/convert.py index 9c90fc85..937d66de 100644 --- a/src/boilercv/manual/convert.py +++ b/src/boilercv/manual/convert.py @@ -7,6 +7,7 @@ def main(): + logger.info("start convert") for source in get_sorted_paths(LOCAL_PATHS.cines): destination = LOCAL_PATHS.large_sources / f"{source.stem}.nc" if destination.exists(): @@ -16,6 +17,7 @@ def main(): except Exception: logger.exception(source.stem) continue + logger.info("finish convert") if __name__ == "__main__": diff --git a/src/boilercv/manual/decompress.py b/src/boilercv/manual/decompress.py index 0edb73d6..7a289c13 100644 --- a/src/boilercv/manual/decompress.py +++ b/src/boilercv/manual/decompress.py @@ -1,27 +1,25 @@ """Decompress sources to local storage.""" +import xarray as xr from loguru import logger -from boilercv.data import ROI, VIDEO -from boilercv.data.packing import pack -from boilercv.data.sets import ALL_NAMES, get_dataset +from boilercv.data import HEADER, VIDEO +from boilercv.data.sets import ALL_NAMES from boilercv.models.params import PARAMS +from boilercv.models.paths import LOCAL_PATHS def main(): - logger.info("start") - destinations = [ - PARAMS.paths.contours / f"{video_name}.h5" for video_name in ALL_NAMES - ] - for source_name, destination in zip(ALL_NAMES, destinations, strict=True): + logger.info("start decompress") + for source_name in ALL_NAMES: + destination = LOCAL_PATHS.uncompressed_sources / f"{source_name}.nc" if destination.exists(): continue - ds = get_dataset(source_name) - ds = ds.drop_vars(ROI) - ds[VIDEO] = pack(ds[VIDEO]) - ds.to_netcdf(path=destination) - logger.info("finish") + source = PARAMS.paths.sources / f"{source_name}.nc" + with xr.open_dataset(source) as ds: + xr.Dataset({VIDEO: ds[VIDEO], HEADER: ds[HEADER]}).to_netcdf(destination) + logger.info("finish decompress") if __name__ == "__main__": diff --git a/src/boilercv/stages/contours.py b/src/boilercv/stages/contours.py index c6a2168d..0773bfe9 100644 --- a/src/boilercv/stages/contours.py +++ b/src/boilercv/stages/contours.py @@ -15,10 +15,8 @@ def main(): logger.info("start contours") - destinations = [ - PARAMS.paths.contours / f"{video_name}.h5" for video_name in ALL_NAMES - ] - for source_name, destination in zip(ALL_NAMES, destinations, strict=True): + for source_name in ALL_NAMES: + destination = PARAMS.paths.contours / f"{source_name}.h5" if destination.exists(): continue video = cv.bitwise_not(scale_bool(get_dataset(source_name)[VIDEO].values)) From 59d546b7a74268e8647bd7510ffe6096ba76f190 Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 13:24:30 -0700 Subject: [PATCH 2/7] Fix contours example --- data/examples.dvc | 4 +- dvc.lock | 4 +- src/boilercv/examples/get_contours.py | 53 ++++++++++----------------- src/boilercv/images/cv.py | 4 +- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/data/examples.dvc b/data/examples.dvc index 5b0b0e54..51825f3f 100644 --- a/data/examples.dvc +++ b/data/examples.dvc @@ -1,5 +1,5 @@ outs: -- md5: 2fb7de8f828795665a28311095a67d20.dir - size: 2171082294 +- md5: 41f9951fa955c5ad93c562a39486dff7.dir + size: 2169856488 nfiles: 5 path: examples diff --git a/dvc.lock b/dvc.lock index 99464397..a355dbae 100644 --- a/dvc.lock +++ b/dvc.lock @@ -49,8 +49,8 @@ stages: size: 7424602696 nfiles: 308 - path: src/boilercv/stages/contours.py - md5: b7593ad6e44a8f0301462d72ae46f1ae - size: 1726 + md5: 18eb0aa2dad3880b985e9c2739531dc9 + size: 1639 outs: - path: data/contours md5: 1c4d2e65a480a5fe014266730896b9f0.dir diff --git a/src/boilercv/examples/get_contours.py b/src/boilercv/examples/get_contours.py index b392cb7a..057e24be 100644 --- a/src/boilercv/examples/get_contours.py +++ b/src/boilercv/examples/get_contours.py @@ -1,8 +1,6 @@ """Get bubble contours.""" import cv2 as cv -import numpy as np -import pandas as pd from boilercv import DEBUG from boilercv.data import VIDEO @@ -11,9 +9,10 @@ from boilercv.examples import EXAMPLE_VIDEO_NAME from boilercv.gui import view_images from boilercv.images import scale_bool -from boilercv.images.cv import draw_contours, find_contours +from boilercv.images.cv import draw_contours from boilercv.models.params import PARAMS -from boilercv.types import DF, Vid +from boilercv.stages.contours import get_all_contours +from boilercv.types import ArrInt, Img NUM_FRAMES = 1000 @@ -21,37 +20,25 @@ def main(): ds = get_dataset(EXAMPLE_VIDEO_NAME, NUM_FRAMES) video = ds[VIDEO] - df = get_all_contours(scale_bool(~video.values), method=cv.CHAIN_APPROX_SIMPLE) - df.to_hdf(PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.h5", "contours") + df = get_all_contours( + cv.bitwise_not(scale_bool(video.values)), method=cv.CHAIN_APPROX_SIMPLE + ) + df.to_hdf( + PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.h5", + "contours", + complib="zlib", + complevel=9, + ) if DEBUG: - result = [ - draw_contours(scale_bool(frame.values), df.loc[idx[i, :, :], :].values) - for i, frame in enumerate(video) - ] - view_images(result) - - -def get_all_contours(video: Vid, method: int = cv.CHAIN_APPROX_NONE) -> DF: - """Get all contours.""" - all_contours = np.vstack( - [ - np.insert( - np.vstack( - [ - np.insert(contour, 0, cont_num, axis=1) - for cont_num, contour in enumerate(find_contours(image, method)) - ] - ), - 0, - image_num, - axis=1, + result: list[Img] = [] + for frame_num, frame in enumerate(video): + contours: list[ArrInt] = list( # type: ignore + df.loc[idx[frame_num], :] # type: ignore + .groupby("contour") + .apply(lambda grp: grp.values) # type: ignore ) - for image_num, image in enumerate(video) - ] - ) - return pd.DataFrame( - all_contours, columns=["frame", "contour", "ypx", "xpx"] - ).set_index(["frame", "contour"]) + result.append(draw_contours(scale_bool(frame.values), contours)) + view_images(result) if __name__ == "__main__": diff --git a/src/boilercv/images/cv.py b/src/boilercv/images/cv.py index 05e5609a..8d28e1b3 100644 --- a/src/boilercv/images/cv.py +++ b/src/boilercv/images/cv.py @@ -113,11 +113,11 @@ def find_contours(img: Img, method: int = cv.CHAIN_APPROX_NONE) -> list[ArrInt]: def draw_contours( - img: Img, contours: ArrInt, contour_index: int = -1, thickness=2 + img: Img, contours: Sequence[ArrInt], contour_index: int = -1, thickness=2 ) -> Img: """Draw contours on an image.""" # OpenCV expects contours as shape (N, 1, 2) instead of (N, 2) - contours = np.fliplr(contours).reshape(-1, 1, 2) + contours = [np.fliplr(contour).reshape(-1, 1, 2) for contour in contours] # Need three-channel image to paint colored contours three_channel_gray = convert_image(img, cv.COLOR_GRAY2RGB) return cv.drawContours( From 959795e3485ae503fd5c444221d591d8caca837f Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 13:25:54 -0700 Subject: [PATCH 3/7] Remove debug step from binarized preview update --- src/boilercv/stages/update_binarized_preview.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/boilercv/stages/update_binarized_preview.py b/src/boilercv/stages/update_binarized_preview.py index 05bfd76d..24a11b70 100644 --- a/src/boilercv/stages/update_binarized_preview.py +++ b/src/boilercv/stages/update_binarized_preview.py @@ -1,11 +1,10 @@ """Update previews for the binarization stage.""" -from boilercv import DEBUG from boilercv.data import FRAME, ROI, VIDEO, VIDEO_NAME, assign_ds from boilercv.data.models import Dimension from boilercv.data.sets import get_all_datasets from boilercv.data.video import XPX_DIM, YPX_DIM -from boilercv.gui import MultipleViewable, pad_images, view_images +from boilercv.gui import MultipleViewable, pad_images from boilercv.models.params import PARAMS @@ -33,8 +32,6 @@ def main(): data=preview, ) ds.to_netcdf(path=PARAMS.paths.binarized_preview) - if DEBUG: - view_images(ds, play_rate=2) if __name__ == "__main__": From f16b59ea44f5dbdcbc55a5e3dc8b9cf1bab9bab7 Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 13:30:28 -0700 Subject: [PATCH 4/7] Alphabetize paths --- src/boilercv/models/paths.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/boilercv/models/paths.py b/src/boilercv/models/paths.py index fb5a82f9..cc01d739 100644 --- a/src/boilercv/models/paths.py +++ b/src/boilercv/models/paths.py @@ -76,16 +76,16 @@ def schema_extra(schema: dict[str, Any]): # ! DATA data: DirectoryPath = Path("data") - examples: DirectoryPath = data / "examples" - - previews: DirectoryPath = data / "previews" - binarized_preview: Path = previews / "binarized.nc" contours: DirectoryPath = data / "contours" + examples: DirectoryPath = data / "examples" rois: DirectoryPath = data / "rois" samples: DirectoryPath = data / "samples" sources: DirectoryPath = data / "sources" + previews: DirectoryPath = data / "previews" + binarized_preview: Path = previews / "binarized.nc" + # ! SCHEMA # Can't be "schema", which is a special member of BaseClass project_schema: DirectoryPath = data / "schema" From a8061e4e7a7dc62ba9485b6ba4d6e00869c653f7 Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 15:04:05 -0700 Subject: [PATCH 5/7] Make old code private --- params.yaml | 6 +++--- src/boilercv/examples/__main__.py | 7 ++----- .../examples/{get_contours.py => contours.py} | 20 +++++++++---------- src/boilercv/examples/contours/__init__.py | 1 - src/boilercv/examples/detect_surface.py | 4 +--- src/boilercv/old/__init__.py | 1 + src/boilercv/old/{build.py => _build.py} | 0 .../bubbles.ipynb => old/_contours.ipynb} | 4 ++-- .../contours/bubbles.py => old/_contours.py} | 5 ++--- .../bubbles_mp4.py => old/_contours_mp4.py} | 0 ...convert_2021_06.py => _convert_2021_06.py} | 0 .../{detect_surface.py => _detect_surface.py} | 4 ++-- .../{remove_prefix.py => _remove_prefix.py} | 0 13 files changed, 22 insertions(+), 30 deletions(-) rename src/boilercv/examples/{get_contours.py => contours.py} (65%) delete mode 100644 src/boilercv/examples/contours/__init__.py rename src/boilercv/old/{build.py => _build.py} (100%) rename src/boilercv/{examples/contours/bubbles.ipynb => old/_contours.ipynb} (91%) rename src/boilercv/{examples/contours/bubbles.py => old/_contours.py} (97%) rename src/boilercv/{examples/contours/bubbles_mp4.py => old/_contours_mp4.py} (100%) rename src/boilercv/old/{convert_2021_06.py => _convert_2021_06.py} (100%) rename src/boilercv/old/{detect_surface.py => _detect_surface.py} (97%) rename src/boilercv/old/{remove_prefix.py => _remove_prefix.py} (100%) diff --git a/params.yaml b/params.yaml index 8fd6d3ff..d5cbc5e9 100644 --- a/params.yaml +++ b/params.yaml @@ -7,13 +7,13 @@ paths: models: src/boilercv/models paths_module: src/boilercv/models/paths.py data: data - examples: data/examples - previews: data/previews - binarized_preview: data/previews/binarized.nc contours: data/contours + examples: data/examples rois: data/rois samples: data/samples sources: data/sources + previews: data/previews + binarized_preview: data/previews/binarized.nc project_schema: data/schema stage_contours: src/boilercv/stages/contours.py stage_schema: src/boilercv/stages/schema.py diff --git a/src/boilercv/examples/__main__.py b/src/boilercv/examples/__main__.py index c03df524..56cb07bb 100644 --- a/src/boilercv/examples/__main__.py +++ b/src/boilercv/examples/__main__.py @@ -5,10 +5,7 @@ from loguru import logger from boilercv.examples.basic_test import main as main2 -from boilercv.examples.blobs.bubbles import main as main4 -from boilercv.examples.blobs.galaxy import main as main3 -from boilercv.examples.contours.bubbles import main as main6 -from boilercv.examples.contours.bubbles_mp4 import main as main5 +from boilercv.examples.contours import main as main3 from boilercv.examples.starry import main as main1 @@ -17,5 +14,5 @@ def run_example(func: Callable[[], None]): func() -for func in (main1, main2, main3, main4, main5, main6): +for func in (main1, main2, main3): run_example(func) diff --git a/src/boilercv/examples/get_contours.py b/src/boilercv/examples/contours.py similarity index 65% rename from src/boilercv/examples/get_contours.py rename to src/boilercv/examples/contours.py index 057e24be..cdfb8dd6 100644 --- a/src/boilercv/examples/get_contours.py +++ b/src/boilercv/examples/contours.py @@ -2,7 +2,6 @@ import cv2 as cv -from boilercv import DEBUG from boilercv.data import VIDEO from boilercv.data.frames import idx from boilercv.data.sets import get_dataset @@ -29,16 +28,15 @@ def main(): complib="zlib", complevel=9, ) - if DEBUG: - result: list[Img] = [] - for frame_num, frame in enumerate(video): - contours: list[ArrInt] = list( # type: ignore - df.loc[idx[frame_num], :] # type: ignore - .groupby("contour") - .apply(lambda grp: grp.values) # type: ignore - ) - result.append(draw_contours(scale_bool(frame.values), contours)) - view_images(result) + result: list[Img] = [] + for frame_num, frame in enumerate(video): + contours: list[ArrInt] = list( # type: ignore + df.loc[idx[frame_num], :] # type: ignore + .groupby("contour") + .apply(lambda grp: grp.values) # type: ignore + ) + result.append(draw_contours(scale_bool(frame.values), contours)) + view_images(result) if __name__ == "__main__": diff --git a/src/boilercv/examples/contours/__init__.py b/src/boilercv/examples/contours/__init__.py deleted file mode 100644 index cfdccb52..00000000 --- a/src/boilercv/examples/contours/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contour-finding examples.""" diff --git a/src/boilercv/examples/detect_surface.py b/src/boilercv/examples/detect_surface.py index e6737931..2bf4ba98 100644 --- a/src/boilercv/examples/detect_surface.py +++ b/src/boilercv/examples/detect_surface.py @@ -40,9 +40,7 @@ def main(): if len(contours) > 1: warn("More than one contour found when searching for the ROI.", stacklevel=1) save_roi(contours[0], EXAMPLE_ROI) - # df = get_all_contours(video.values, method=cv.CHAIN_APPROX_SIMPLE) - if DEBUG: - view_images(dict(boiling_surface=boiling_surface, roi=roi)) + view_images(dict(boiling_surface=boiling_surface, roi=roi)) def find_boiling_surface(img: Img) -> tuple[Img, ArrInt]: diff --git a/src/boilercv/old/__init__.py b/src/boilercv/old/__init__.py index e69de29b..534fe615 100644 --- a/src/boilercv/old/__init__.py +++ b/src/boilercv/old/__init__.py @@ -0,0 +1 @@ +"""Routines that are not currently being used.""" diff --git a/src/boilercv/old/build.py b/src/boilercv/old/_build.py similarity index 100% rename from src/boilercv/old/build.py rename to src/boilercv/old/_build.py diff --git a/src/boilercv/examples/contours/bubbles.ipynb b/src/boilercv/old/_contours.ipynb similarity index 91% rename from src/boilercv/examples/contours/bubbles.ipynb rename to src/boilercv/old/_contours.ipynb index c9779ddd..1fd76d27 100644 --- a/src/boilercv/examples/contours/bubbles.ipynb +++ b/src/boilercv/old/_contours.ipynb @@ -10,7 +10,7 @@ "\n", "from ipywidgets import fixed, interact\n", "\n", - "from boilercv.examples.contours.bubbles import preview_contours\n", + "from boilercv.old._contours import preview_contours\n", "\n", "_ = interact(\n", " preview_contours,\n", @@ -19,7 +19,7 @@ " contour_index=fixed(-1),\n", " thickness=fixed(2),\n", " interact=fixed(True),\n", - ")" + ")\n" ] } ], diff --git a/src/boilercv/examples/contours/bubbles.py b/src/boilercv/old/_contours.py similarity index 97% rename from src/boilercv/examples/contours/bubbles.py rename to src/boilercv/old/_contours.py index d3b61258..510bae5e 100644 --- a/src/boilercv/examples/contours/bubbles.py +++ b/src/boilercv/old/_contours.py @@ -1,6 +1,5 @@ """Given a CINE, find ROI using `pyqtgraph` and find contours.""" - from matplotlib.pyplot import subplot_mosaic from boilercv.examples import EXAMPLE_FRAME_LIST, EXAMPLE_ROI @@ -48,7 +47,7 @@ def preview_contours( contoured=contoured, ) for image in input_images: - contours, masked, thresholded = get_contours( + contours, masked, thresholded = _get_contours( image, roi, block_size, thresh_dist_from_mean ) all_contours.append(contours) @@ -62,7 +61,7 @@ def preview_contours( return all_contours -def get_contours( +def _get_contours( input_image: ArrInt, roi: ArrInt, block_size: int, diff --git a/src/boilercv/examples/contours/bubbles_mp4.py b/src/boilercv/old/_contours_mp4.py similarity index 100% rename from src/boilercv/examples/contours/bubbles_mp4.py rename to src/boilercv/old/_contours_mp4.py diff --git a/src/boilercv/old/convert_2021_06.py b/src/boilercv/old/_convert_2021_06.py similarity index 100% rename from src/boilercv/old/convert_2021_06.py rename to src/boilercv/old/_convert_2021_06.py diff --git a/src/boilercv/old/detect_surface.py b/src/boilercv/old/_detect_surface.py similarity index 97% rename from src/boilercv/old/detect_surface.py rename to src/boilercv/old/_detect_surface.py index 456264a7..1488b76f 100644 --- a/src/boilercv/old/detect_surface.py +++ b/src/boilercv/old/_detect_surface.py @@ -12,7 +12,7 @@ from boilercv.types import DA, ArrInt -def find_boiling_surface2(image: DA, preview: bool = DEBUG) -> ArrInt: +def _find_boiling_surface(image: DA, preview: bool = DEBUG) -> ArrInt: """Find the boiling surface.""" # Find corners and set index to contour points for later concatenation (height, width) = image.shape @@ -77,7 +77,7 @@ def find_boiling_surface2(image: DA, preview: bool = DEBUG) -> ArrInt: return candidates.values.flatten()[:2] -def find_boiling_surface3(image): +def _find_boiling_surface2(image): """Get line segments in an image.""" lines_, lsd = find_line_segments(image) lined = lsd.drawSegments(image, lines_) diff --git a/src/boilercv/old/remove_prefix.py b/src/boilercv/old/_remove_prefix.py similarity index 100% rename from src/boilercv/old/remove_prefix.py rename to src/boilercv/old/_remove_prefix.py From 2d7fe43faffaeaa4baf2c4ed10b17a6970558c9f Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 15:43:38 -0700 Subject: [PATCH 6/7] Prepare to fill contours --- data/examples.dvc | 2 +- dvc.lock | 6 +++--- src/boilercv/examples/__init__.py | 24 +++++------------------- src/boilercv/examples/blobs/bubbles.py | 5 ++--- src/boilercv/examples/contours.py | 14 +++----------- src/boilercv/examples/detect_surface.py | 6 ++---- src/boilercv/examples/fill.py | 9 +++++++++ src/boilercv/examples/large/convert.py | 5 ++--- src/boilercv/old/_contours_mp4.py | 16 ++++++++++++++-- 9 files changed, 41 insertions(+), 46 deletions(-) create mode 100644 src/boilercv/examples/fill.py diff --git a/data/examples.dvc b/data/examples.dvc index 51825f3f..4af8addd 100644 --- a/data/examples.dvc +++ b/data/examples.dvc @@ -1,5 +1,5 @@ outs: -- md5: 41f9951fa955c5ad93c562a39486dff7.dir +- md5: d0e378db3ed75907019882c2b76adf83.dir size: 2169856488 nfiles: 5 path: examples diff --git a/dvc.lock b/dvc.lock index a355dbae..72a63427 100644 --- a/dvc.lock +++ b/dvc.lock @@ -4,7 +4,7 @@ stages: cmd: python -m boilercv.stages.schema deps: - path: src/boilercv/models/paths.py - md5: 4505c3e4ae283c3ee576c06dce722714 + md5: 88b036c3649bb3b7fca150eb18a9f081 size: 3549 - path: src/boilercv/stages/schema.py md5: 6eaac97ab24e94f410ccff1517f42d0e @@ -26,8 +26,8 @@ stages: size: 7424602696 nfiles: 308 - path: src/boilercv/stages/update_binarized_preview.py - md5: f97c70b2c05bc67f5093ee0a0b3f8f71 - size: 1247 + md5: 186799fb6a90ec27a63cb274e05eca54 + size: 1153 outs: - path: data/previews/binarized.nc md5: 5598ee8b69f8591e2035194a9054f2c3 diff --git a/src/boilercv/examples/__init__.py b/src/boilercv/examples/__init__.py index 7cb6565b..0be3b14c 100644 --- a/src/boilercv/examples/__init__.py +++ b/src/boilercv/examples/__init__.py @@ -1,36 +1,22 @@ """Examples, experiments, and demonstrations.""" -from collections.abc import Iterator -from pathlib import Path - -import cv2 as cv import xarray as xr from boilercv.data import VIDEO from boilercv.models.params import PARAMS -from boilercv.types import DA, Img +from boilercv.types import DA +EXAMPLE_NUM_FRAMES = 1000 EXAMPLE_VIDEO_NAME = "2022-11-30T13-41-00" -SOURCE = PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.nc" -NUM_FRAMES = 300 +EXAMPLE_CONTOURS = PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.h5" # TODO: Source the ROI from the dataset. EXAMPLE_ROI = PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}_roi.yaml" def get_images() -> DA: - with xr.open_dataset(SOURCE) as ds: - return ds[VIDEO].sel(frame=slice(None, NUM_FRAMES)) + with xr.open_dataset(PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.nc") as ds: + return ds[VIDEO].sel(frame=slice(None, EXAMPLE_NUM_FRAMES)) EXAMPLE_VIDEO = get_images() EXAMPLE_FRAME_LIST = list(EXAMPLE_VIDEO.values) - - -def capture_images(path: Path) -> Iterator[Img]: - """Images from a video file.""" - video_capture = cv.VideoCapture(str(path)) - while True: - read_is_successful, image = video_capture.read() - if not read_is_successful: - break - yield image diff --git a/src/boilercv/examples/blobs/bubbles.py b/src/boilercv/examples/blobs/bubbles.py index 45530795..444e6ce4 100644 --- a/src/boilercv/examples/blobs/bubbles.py +++ b/src/boilercv/examples/blobs/bubbles.py @@ -1,6 +1,5 @@ """Find bubbles as blobs.""" - import cv2 as cv from boilercv.colors import RED @@ -10,8 +9,8 @@ from boilercv.images.cv import apply_mask, build_mask_from_polygons, convert_image from boilercv.types import ArrInt -NUM_FRAMES = 10 -SHORTER_FRAME_LIST = EXAMPLE_FRAME_LIST[:NUM_FRAMES] +_NUM_FRAMES = 10 +SHORTER_FRAME_LIST = EXAMPLE_FRAME_LIST[:_NUM_FRAMES] def main(): diff --git a/src/boilercv/examples/contours.py b/src/boilercv/examples/contours.py index cdfb8dd6..f8df79b8 100644 --- a/src/boilercv/examples/contours.py +++ b/src/boilercv/examples/contours.py @@ -5,29 +5,21 @@ from boilercv.data import VIDEO from boilercv.data.frames import idx from boilercv.data.sets import get_dataset -from boilercv.examples import EXAMPLE_VIDEO_NAME +from boilercv.examples import EXAMPLE_CONTOURS, EXAMPLE_NUM_FRAMES, EXAMPLE_VIDEO_NAME from boilercv.gui import view_images from boilercv.images import scale_bool from boilercv.images.cv import draw_contours -from boilercv.models.params import PARAMS from boilercv.stages.contours import get_all_contours from boilercv.types import ArrInt, Img -NUM_FRAMES = 1000 - def main(): - ds = get_dataset(EXAMPLE_VIDEO_NAME, NUM_FRAMES) + ds = get_dataset(EXAMPLE_VIDEO_NAME, EXAMPLE_NUM_FRAMES) video = ds[VIDEO] df = get_all_contours( cv.bitwise_not(scale_bool(video.values)), method=cv.CHAIN_APPROX_SIMPLE ) - df.to_hdf( - PARAMS.paths.examples / f"{EXAMPLE_VIDEO_NAME}.h5", - "contours", - complib="zlib", - complevel=9, - ) + df.to_hdf(EXAMPLE_CONTOURS, "contours", complib="zlib", complevel=9) result: list[Img] = [] for frame_num, frame in enumerate(video): contours: list[ArrInt] = list( # type: ignore diff --git a/src/boilercv/examples/detect_surface.py b/src/boilercv/examples/detect_surface.py index 2bf4ba98..2bed600d 100644 --- a/src/boilercv/examples/detect_surface.py +++ b/src/boilercv/examples/detect_surface.py @@ -16,17 +16,15 @@ from boilercv.data import VIDEO, YX_PX, apply_to_img_da from boilercv.data.frames import df_points from boilercv.data.sets import get_dataset -from boilercv.examples import EXAMPLE_ROI, EXAMPLE_VIDEO_NAME +from boilercv.examples import EXAMPLE_NUM_FRAMES, EXAMPLE_ROI, EXAMPLE_VIDEO_NAME from boilercv.gui import get_calling_scope_name, save_roi, view_images from boilercv.images import scale_bool from boilercv.images.cv import find_contours, get_wall from boilercv.types import DA, ArrInt, Img -NUM_FRAMES = 1000 - def main(): - ds = get_dataset(EXAMPLE_VIDEO_NAME, NUM_FRAMES) + ds = get_dataset(EXAMPLE_VIDEO_NAME, EXAMPLE_NUM_FRAMES) video = ds[VIDEO] roi = ds["roi"] wall: DA = apply_to_img_da(get_wall, scale_bool(roi), name="wall") diff --git a/src/boilercv/examples/fill.py b/src/boilercv/examples/fill.py new file mode 100644 index 00000000..ff779c08 --- /dev/null +++ b/src/boilercv/examples/fill.py @@ -0,0 +1,9 @@ +"""Fill bubble contours.""" + + +def main(): + ... + + +if __name__ == "__main__": + main() diff --git a/src/boilercv/examples/large/convert.py b/src/boilercv/examples/large/convert.py index 19c61800..5bcd6d63 100644 --- a/src/boilercv/examples/large/convert.py +++ b/src/boilercv/examples/large/convert.py @@ -1,16 +1,15 @@ """Convert CINE files to the NetCDF file format.""" from boilercv.data.video import prepare_dataset +from boilercv.examples import EXAMPLE_NUM_FRAMES from boilercv.models.paths import LOCAL_PATHS -NUM_FRAMES = 100 - def main(): destination = ( LOCAL_PATHS.large_examples / f"{LOCAL_PATHS.large_example_cine.stem}.nc" ) - ds = prepare_dataset(LOCAL_PATHS.large_example_cine, num_frames=NUM_FRAMES) + ds = prepare_dataset(LOCAL_PATHS.large_example_cine, num_frames=EXAMPLE_NUM_FRAMES) ds.to_netcdf(path=destination) diff --git a/src/boilercv/old/_contours_mp4.py b/src/boilercv/old/_contours_mp4.py index 57bb61d6..11cb69a0 100644 --- a/src/boilercv/old/_contours_mp4.py +++ b/src/boilercv/old/_contours_mp4.py @@ -1,11 +1,13 @@ """Given an MP4, find ROI using `opencv` and find contours.""" +from collections.abc import Iterator +from pathlib import Path + import cv2 as cv import numpy as np from scipy.spatial import ConvexHull from boilercv.colors import BLUE_CV -from boilercv.examples import capture_images from boilercv.images import scale_bool from boilercv.images.cv import ( apply_mask, @@ -16,7 +18,7 @@ find_contours, ) from boilercv.models.params import PARAMS -from boilercv.types import ArrInt +from boilercv.types import ArrInt, Img WINDOW_NAME = "image" ESC_KEY = ord("\x1b") @@ -95,5 +97,15 @@ def draw_hull(hull: ConvexHull, image: ArrInt) -> ArrInt: return main() +def capture_images(path: Path) -> Iterator[Img]: + """Images from a video file.""" + video_capture = cv.VideoCapture(str(path)) + while True: + read_is_successful, image = video_capture.read() + if not read_is_successful: + break + yield image + + if __name__ == "__main__": main() From 98d4401483e90c23e17825624f16440c252f432a Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 5 Apr 2023 15:45:26 -0700 Subject: [PATCH 7/7] Remove repro from tests now that it is time-consuming --- tests/test_boilercv.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_boilercv.py b/tests/test_boilercv.py index a1525764..1b486a16 100644 --- a/tests/test_boilercv.py +++ b/tests/test_boilercv.py @@ -1,6 +1,3 @@ -from subprocess import run - - -def test_repro(): - """Test that the pipeline can be reproduced.""" - run(["dvc", "repro", "-f"]) +def test_import(): + """Import test.""" + import boilercv # noqa: F401