From 99b19238cbffedeae8e6cd2b29086ff8ecf2bfb3 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 16:26:31 -0400
Subject: [PATCH 1/8] Use geowatch-dvc for example paths

---
 geowatch/tasks/poly_from_point/predict.py | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index bc023e9c6..2ea2f9747 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -130,7 +130,7 @@ def extract_sam_polygons(
 
     for idx, mask in enumerate(all_predicted_regions):
         try:
-            res = mask > (.45) 
+            res = mask > (.45)
             # point_row = region_gdf_utm.iloc[idx]
             mask = kwimage.Mask(res, "c_mask")
             polygon = mask.to_multi_polygon()
@@ -194,7 +194,7 @@ def convert_polygons_to_region_model(
                 raise Exception
             polygon_video_space = polygon.convex_hull
             polygon_video_space.to_shapely()
-            
+
         except Exception:
             continue
             raise NotImplementedError('fixme define default polygon')
@@ -202,7 +202,7 @@ def convert_polygons_to_region_model(
             polygon_video_space = default_polygon
             vid_space_summaries.append(properties)
             vid_space_geometries.append(polygon_video_space)
-  
+
         else:
             vid_space_summaries.append(properties)
             vid_space_geometries.append(polygon_video_space)
@@ -340,7 +340,6 @@ def get_points(video_obj, filepath_to_points):
     return region_points_gdf_vidspace, warp_vid_from_wld, region_gdf_utm, region_gdf_crs84
 
 
-# TODO: add hard coded to config
 def main():
     r"""
     IGNORE:
@@ -352,13 +351,17 @@ def main():
 
 
     Ignore:
+        DVC_DATA_DPATH=$(geowatch_dvc --tags='phase3_data' --hardware=auto)
+        DVC_EXPT_DPATH=$(geowatch_dvc --tags='phase3_expt' --hardware=auto)
+        echo "$DVC_DATA_DPATH"
+        echo "$DVC_EXPT_DPATH"
+
         python -m geowatch.tasks.poly_from_point.predict \
             --method 'sam' \
-            --filepath_to_images "$HOME/data/dvc-repos/smart_phase3_data/Aligned-Drop8-ARA/KR_R001/imganns-KR_R001-rawbands.kwcoco.zip" \
-            --filepath_to_points "$HOME/data/dvc-repos/smart_phase3_data/annotations/point_based_annotations.zip" \
-            --filepath_to_region "$HOME/data/dvc-repos/smart_phase3_data/annotations/drop8/region_models/KR_R001.geojson" \
-            --filepath_to_sam /home/joncrall/data/dvc-repos/smart_phase3_expt/models/sam/sam_vit_h_4b8939.pth
-
+            --filepath_to_images "$DVC_DATA_DPATH/Aligned-Drop8-ARA/KR_R001/imganns-KR_R001-rawbands.kwcoco.zip" \
+            --filepath_to_points "$DVC_DATA_DPATH/annotations/point_based_annotations.zip" \
+            --filepath_to_region "$DVC_DATA_DPATH/annotations/drop8/region_models/KR_R001.geojson" \
+            --filepath_to_sam "$DVC_EXPT_DPATH/models/sam/sam_vit_h_4b8939.pth"
     """
     config = HeatMapConfig.cli(cmdline=1)
     import rich
-- 
GitLab


From 01ea9e757a3834b701b6cd212845cf2e81d66837 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 16:28:12 -0400
Subject: [PATCH 2/8] Consolidate common code between box and sam

---
 geowatch/tasks/poly_from_point/predict.py | 37 +++++++++--------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index 2ea2f9747..917755de7 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -362,6 +362,11 @@ def main():
             --filepath_to_points "$DVC_DATA_DPATH/annotations/point_based_annotations.zip" \
             --filepath_to_region "$DVC_DATA_DPATH/annotations/drop8/region_models/KR_R001.geojson" \
             --filepath_to_sam "$DVC_EXPT_DPATH/models/sam/sam_vit_h_4b8939.pth"
+
+        python -m geowatch.tasks.poly_from_point.predict \
+            --method 'box' \
+            --filepath_to_points "$DVC_DATA_DPATH/annotations/point_based_annotations.zip" \
+            --filepath_to_region "$DVC_DATA_DPATH/annotations/drop8/region_models/KR_R001.geojson" \
     """
     config = HeatMapConfig.cli(cmdline=1)
     import rich
@@ -400,19 +405,6 @@ def main():
             "cxywh",
         )
         polygons = regions.to_polygons()
-
-        result = convert_polygons_to_region_model(
-            polygons,
-            main_region_header,
-            warp_vid_from_wld,
-            region_gdf_utm,
-            region_gdf_crs84,
-            time_pad,
-        )
-        output = ub.Path(output)
-        output.write_text(result.dumps())
-
-        ...
     if method == "sam":
         count_individual_mask = 0
 
@@ -490,16 +482,15 @@ def main():
             )
         )
 
-        result = convert_polygons_to_region_model(
-            polygons,
-            main_region_header,
-            warp_vid_from_wld,
-            region_gdf_utm,
-            region_gdf_crs84,
-            time_pad,
-        )
-        print(result.dumps())
-        output.write_text(result.dumps())
+    result = convert_polygons_to_region_model(
+        polygons,
+        main_region_header,
+        warp_vid_from_wld,
+        region_gdf_utm,
+        region_gdf_crs84,
+        time_pad,
+    )
+    output.write_text(result.dumps())
 
 
 if __name__ == "__main__":
-- 
GitLab


From b9d7fc48bef0ba8456c79631cf13b05f9b8dc5a5 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 16:32:31 -0400
Subject: [PATCH 3/8] Update docs with example for gen->draw pipeline

---
 geowatch/tasks/poly_from_point/predict.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index 917755de7..82f3c72ba 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -351,7 +351,7 @@ def main():
 
 
     Ignore:
-        DVC_DATA_DPATH=$(geowatch_dvc --tags='phase3_data' --hardware=auto)
+        DVC_DATA_DPATH=$(geowatch_dvc --tags='phase3_data' --hardware=hdd)
         DVC_EXPT_DPATH=$(geowatch_dvc --tags='phase3_expt' --hardware=auto)
         echo "$DVC_DATA_DPATH"
         echo "$DVC_EXPT_DPATH"
@@ -365,8 +365,12 @@ def main():
 
         python -m geowatch.tasks.poly_from_point.predict \
             --method 'box' \
+            --file_output KR_R001-genpoints.geojson \
+            --filepath_to_images "$DVC_DATA_DPATH/Aligned-Drop8-ARA/KR_R001/imganns-KR_R001-rawbands.kwcoco.zip" \
             --filepath_to_points "$DVC_DATA_DPATH/annotations/point_based_annotations.zip" \
             --filepath_to_region "$DVC_DATA_DPATH/annotations/drop8/region_models/KR_R001.geojson" \
+
+        geowatch draw_region KR_R001-genpoints.geojson --fpath KR_R001-genpoints.png
     """
     config = HeatMapConfig.cli(cmdline=1)
     import rich
@@ -490,6 +494,7 @@ def main():
         region_gdf_crs84,
         time_pad,
     )
+    print(f'Writing output to {output}')
     output.write_text(result.dumps())
 
 
-- 
GitLab


From e7632eed0413e26afc13b9899a78afdb9ae54e2b Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 16:36:08 -0400
Subject: [PATCH 4/8] Use status from point geojson

---
 geowatch/tasks/poly_from_point/predict.py | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index 82f3c72ba..a1ef231e4 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -172,16 +172,22 @@ def convert_polygons_to_region_model(
         mid_date = kwutil.util_time.datetime.coerce(point_row_utm["date"])
         start_date = mid_date - time_pad
         end_date = mid_date + time_pad
+
+        status = point_row_crs84.status
+        if status == 'positive':
+            # Translate to a valid T&E positive name
+            status = 'positive_pending'
+
         properties = {
             "type": "site_summary",
-            "status": "positive_annotated",
+            "status": status,
             "version": "2.0.1",
             "site_id": point_row_utm["site_id"],
             "mgrs": main_region_header["properties"]["mgrs"],
             "start_date": start_date.date().isoformat(),
             "end_date": end_date.date().isoformat(),
             "score": 1,
-            "originator": "Rutgers_SAM",
+            "originator": "poly_from_point",  # TODO: add some config info here
             "model_content": "annotation",
             "validated": "False",
             "cache": {
-- 
GitLab


From d78231e235ebfe1344728335fa298d9ac3442fa6 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 16:59:01 -0400
Subject: [PATCH 5/8] Allow specification of box priors in physical units

---
 geowatch/tasks/poly_from_point/predict.py | 59 ++++++++++++++++-------
 1 file changed, 42 insertions(+), 17 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index a1ef231e4..a54a443fc 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -103,16 +103,25 @@ class HeatMapConfig(scfg.DataConfig):
         help="Filepath to SAM model",
     )
     file_output = scfg.Value("KR_R002-SAM.geojson", help="Output dest")
-    box_size = scfg.Value(
-        [20.06063, 20.0141229],
-        help="Specify Bounding Box for SAM to use during prediction",
+
+    size_prior = scfg.Value(
+        "20.06063 x 20.0141229 @ 10mGSD",
+        help=ub.paragraph(
+            '''
+            The expected size of the objects in world coorindates.
+            Must be specified as
+            ``<w> x <h> @ <magnitude> <resolution>``. E.g.  ``20x25@10mGSD``
+            will assume objects 200 by 250 meters.
+            '''
+        ),
+        alias=['box_size']
     )
 
     method = scfg.Value(
-        "sam", choices=["sam", "box"], help="Method for extracting polygons from points"
+        "sam", choices=["sam", "box", "ellipse"], help="Method for extracting polygons from points"
     )
 
-    time_pad = scfg.Value('1 year', help='time prior before and after')
+    time_prior = scfg.Value('1 year', help='time prior before and after', alias=['time_pad'])
 
 
 def extract_sam_polygons(
@@ -149,7 +158,7 @@ def convert_polygons_to_region_model(
     warp_vid_from_wld,
     region_gdf_utm,
     region_gdf_crs84,
-    time_pad,
+    time_prior,
 ):
     print(f"{len(polygons)=}")
     """
@@ -170,8 +179,8 @@ def convert_polygons_to_region_model(
         point_row_crs84 = region_gdf_crs84.iloc[idx]
         assert point_row_crs84['site_id'] == point_row_utm['site_id']
         mid_date = kwutil.util_time.datetime.coerce(point_row_utm["date"])
-        start_date = mid_date - time_pad
-        end_date = mid_date + time_pad
+        start_date = mid_date - time_prior
+        end_date = mid_date + time_prior
 
         status = point_row_crs84.status
         if status == 'positive':
@@ -370,8 +379,9 @@ def main():
             --filepath_to_sam "$DVC_EXPT_DPATH/models/sam/sam_vit_h_4b8939.pth"
 
         python -m geowatch.tasks.poly_from_point.predict \
-            --method 'box' \
+            --method 'ellipse' \
             --file_output KR_R001-genpoints.geojson \
+            --size_prior "20@10mGSD" \
             --filepath_to_images "$DVC_DATA_DPATH/Aligned-Drop8-ARA/KR_R001/imganns-KR_R001-rawbands.kwcoco.zip" \
             --filepath_to_points "$DVC_DATA_DPATH/annotations/point_based_annotations.zip" \
             --filepath_to_region "$DVC_DATA_DPATH/annotations/drop8/region_models/KR_R001.geojson" \
@@ -381,10 +391,12 @@ def main():
     config = HeatMapConfig.cli(cmdline=1)
     import rich
     from rich.markup import escape
+
     rich.print(f'config = {escape(ub.urepr(config, nl=1))}')
 
-    box_width = config.box_size[0]
-    box_height = config.box_size[1]
+    from geowatch.utils import util_resolution
+    size_prior = util_resolution.ResolvedWindow.coerce(config.size_prior)
+
     filepath_to_images = config.filepath_to_images
     filepath_to_sam = config.filepath_to_sam
     filepath_to_points = config.filepath_to_points
@@ -393,7 +405,7 @@ def main():
     output = ub.Path(config.file_output)
     main_region = RegionModel.coerce(filepath_to_region)
     main_region_header = main_region.header
-    time_pad = kwutil.util_time.timedelta.coerce(config.time_pad)
+    time_prior = kwutil.util_time.timedelta.coerce(config.time_prior)
 
     main_region_header["properties"]["originator"] = "Rutgers"
     main_region_header["properties"]["comments"] = "SAM Points"
@@ -403,18 +415,31 @@ def main():
     #  above points directly, but for completeness this example demonstrates
     #  how to warp them all the way down to the image level.)
     dset = kwcoco.CocoDataset(filepath_to_images)
+
+    assert dset.n_videos == 1, 'only handling 1 video for now'
+
     video_obj = list(dset.videos().objs)[0]
     video_image_ids = dset.images(video_id=video_obj["id"])
 
+    video_space_gsd = util_resolution.ResolvedUnit.coerce(str(video_obj['target_gsd']) + ' mGSD')
+
+    # Convert the size prior to video space
+    vidspace_size_prior = size_prior.at_resolution(video_space_gsd)
+    prior_width, prior_height = vidspace_size_prior.window
+
     region_points_gdf_vidspace, warp_vid_from_wld, region_gdf_utm, region_gdf_crs84 = get_points(
         video_obj, filepath_to_points
     )
     if method == "box":
-        regions = kwimage.Boxes(
-            [[p.x, p.y, box_width, box_height] for p in region_points_gdf_vidspace],
+        polygons = kwimage.Boxes(
+            [[p.x, p.y, prior_width, prior_height] for p in region_points_gdf_vidspace],
             "cxywh",
-        )
-        polygons = regions.to_polygons()
+        ).to_polygons()
+    if method == "ellipse":
+        polygons = [
+            kwimage.Polygon.circle(xy=(p.x, p.y), r=(prior_width, prior_height))
+            for p in region_points_gdf_vidspace
+        ]
     if method == "sam":
         count_individual_mask = 0
 
@@ -498,7 +523,7 @@ def main():
         warp_vid_from_wld,
         region_gdf_utm,
         region_gdf_crs84,
-        time_pad,
+        time_prior,
     )
     print(f'Writing output to {output}')
     output.write_text(result.dumps())
-- 
GitLab


From 089579ac26fa29bdce9f13ca87aa58acf45e0f90 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 17:03:45 -0400
Subject: [PATCH 6/8] Ran black

---
 geowatch/tasks/poly_from_point/Run_All_SAM.py | 60 +++++++++-------
 geowatch/tasks/poly_from_point/predict.py     | 72 +++++++++++--------
 2 files changed, 76 insertions(+), 56 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/Run_All_SAM.py b/geowatch/tasks/poly_from_point/Run_All_SAM.py
index f17086c05..c256aace3 100644
--- a/geowatch/tasks/poly_from_point/Run_All_SAM.py
+++ b/geowatch/tasks/poly_from_point/Run_All_SAM.py
@@ -1,36 +1,46 @@
 def main():
     import cmd_queue
     import ubelt as ub
-    queue = cmd_queue.Queue.create(backend='tmux',size=4)
-    queue.add_header_command(ub.codeblock(
-        '''
-        pyenv shell 3.10.5
-        source $(pyenv prefix)/envs/pyenv-geowatch/bin/activate
 
-        '''
-    ))
-    template = ub.codeblock(r'''
-            python -m geowatch.tasks.poly_from_point.predict \
-            --method 'sam' \
-            --filepath_to_images "{file_path_to_images}" \
-            --filepath_to_region "{file_path_to_region}" \
-            ''')
-    region_model_path= ub.Path("/mnt/ssd2/data/dvc-repos/smart_phase3_data/annotations/drop8/region_models/")
-    region_model_list = list(region_model_path.glob('*.geojson'))
-    kwcoco_dpath =ub.Path("/mnt/ssd2/data/dvc-repos/smart_phase3_data/Aligned-Drop8-ARA/")
+    queue = cmd_queue.Queue.create(backend="tmux", size=4)
+    queue.add_header_command(
+        ub.codeblock(
+            """
+            pyenv shell 3.10.5
+            source $(pyenv prefix)/envs/pyenv-geowatch/bin/activate
+            """
+        )
+    )
+    template = ub.codeblock(
+        r"""
+        python -m geowatch.tasks.poly_from_point.predict \
+        --method 'sam' \
+        --filepath_to_images "{file_path_to_images}" \
+        --filepath_to_region "{file_path_to_region}" \
+        """
+    )
+    region_model_path = ub.Path(
+        "/mnt/ssd2/data/dvc-repos/smart_phase3_data/annotations/drop8/region_models/"
+    )
+    region_model_list = list(region_model_path.glob("*.geojson"))
+    kwcoco_dpath = ub.Path(
+        "/mnt/ssd2/data/dvc-repos/smart_phase3_data/Aligned-Drop8-ARA/"
+    )
     for region_path in region_model_list:
         region_id = region_path.stem
-        kwcoco_path = kwcoco_dpath / region_id /(f'imgonly-{region_id}-rawbands.kwcoco.zip')
-        if(kwcoco_path.exists()):
-            fmtkw={'file_path_to_images':kwcoco_path,
-                   'file_path_to_region':region_path}
-            cmd=template.format(**fmtkw)
-            queue.submit(cmd,name=f'From point: {region_id} ')
+        kwcoco_path = (
+            kwcoco_dpath / region_id / (f"imgonly-{region_id}-rawbands.kwcoco.zip")
+        )
+        if kwcoco_path.exists():
+            fmtkw = {
+                "file_path_to_images": kwcoco_path,
+                "file_path_to_region": region_path,
+            }
+            cmd = template.format(**fmtkw)
+            queue.submit(cmd, name=f"From point: {region_id} ")
     queue.print_commands()
     queue.run()
 
+
 if __name__ == "__main__":
     main()
-
-
-
diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index a54a443fc..4809fd06c 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -107,21 +107,25 @@ class HeatMapConfig(scfg.DataConfig):
     size_prior = scfg.Value(
         "20.06063 x 20.0141229 @ 10mGSD",
         help=ub.paragraph(
-            '''
+            """
             The expected size of the objects in world coorindates.
             Must be specified as
             ``<w> x <h> @ <magnitude> <resolution>``. E.g.  ``20x25@10mGSD``
             will assume objects 200 by 250 meters.
-            '''
+            """
         ),
-        alias=['box_size']
+        alias=["box_size"],
     )
 
     method = scfg.Value(
-        "sam", choices=["sam", "box", "ellipse"], help="Method for extracting polygons from points"
+        "sam",
+        choices=["sam", "box", "ellipse"],
+        help="Method for extracting polygons from points",
     )
 
-    time_prior = scfg.Value('1 year', help='time prior before and after', alias=['time_pad'])
+    time_prior = scfg.Value(
+        "1 year", help="time prior before and after", alias=["time_pad"]
+    )
 
 
 def extract_sam_polygons(
@@ -139,7 +143,7 @@ def extract_sam_polygons(
 
     for idx, mask in enumerate(all_predicted_regions):
         try:
-            res = mask > (.45)
+            res = mask > (0.45)
             # point_row = region_gdf_utm.iloc[idx]
             mask = kwimage.Mask(res, "c_mask")
             polygon = mask.to_multi_polygon()
@@ -177,15 +181,15 @@ def convert_polygons_to_region_model(
     for idx, polygon in enumerate(polygons):
         point_row_utm = region_gdf_utm.iloc[idx]
         point_row_crs84 = region_gdf_crs84.iloc[idx]
-        assert point_row_crs84['site_id'] == point_row_utm['site_id']
+        assert point_row_crs84["site_id"] == point_row_utm["site_id"]
         mid_date = kwutil.util_time.datetime.coerce(point_row_utm["date"])
         start_date = mid_date - time_prior
         end_date = mid_date + time_prior
 
         status = point_row_crs84.status
-        if status == 'positive':
+        if status == "positive":
             # Translate to a valid T&E positive name
-            status = 'positive_pending'
+            status = "positive_pending"
 
         properties = {
             "type": "site_summary",
@@ -205,14 +209,14 @@ def convert_polygons_to_region_model(
             },
         }
         try:
-            if polygon is None :
+            if polygon is None:
                 raise Exception
             polygon_video_space = polygon.convex_hull
             polygon_video_space.to_shapely()
 
         except Exception:
             continue
-            raise NotImplementedError('fixme define default polygon')
+            raise NotImplementedError("fixme define default polygon")
             default_polygon = NotImplemented
             polygon_video_space = default_polygon
             vid_space_summaries.append(properties)
@@ -263,7 +267,6 @@ def image_predicted(
 
 
 def show_mask(mask, ax, random_color=False):
-
     color = np.array([255 / 255, 255 / 255, 255 / 255, 1.0])
     h, w = mask.shape[-2:]
     mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
@@ -272,7 +275,6 @@ def show_mask(mask, ax, random_color=False):
 
 
 def read_points_anns(filepath_to_points):
-
     fpath = filepath_to_points
     # Read json text directly from the zipfile
     file = ub.zopen(fpath + "/" + "point_based_annotations.geojson", "r")
@@ -299,7 +301,6 @@ def load_sam(filepath_to_sam):
 
 
 def comput_average_boxes(dset):
-
     total = []
     for gid in range(len(dset.images().coco_images)):
         coco_img = dset.images().coco_images[gid]
@@ -330,7 +331,6 @@ def comput_average_boxes(dset):
 # TODO: GENERALIZE FOR ALL REGIONS
 # Pick one region coco file
 def get_points(video_obj, filepath_to_points):
-
     # Find the world-space CRS for this region
     video_crs = util_gis.coerce_crs(video_obj["wld_crs_info"])
 
@@ -352,7 +352,12 @@ def get_points(video_obj, filepath_to_points):
         warp_vid_from_wld.to_shapely()
     )
 
-    return region_points_gdf_vidspace, warp_vid_from_wld, region_gdf_utm, region_gdf_crs84
+    return (
+        region_points_gdf_vidspace,
+        warp_vid_from_wld,
+        region_gdf_utm,
+        region_gdf_crs84,
+    )
 
 
 def main():
@@ -392,9 +397,10 @@ def main():
     import rich
     from rich.markup import escape
 
-    rich.print(f'config = {escape(ub.urepr(config, nl=1))}')
+    rich.print(f"config = {escape(ub.urepr(config, nl=1))}")
 
     from geowatch.utils import util_resolution
+
     size_prior = util_resolution.ResolvedWindow.coerce(config.size_prior)
 
     filepath_to_images = config.filepath_to_images
@@ -416,20 +422,25 @@ def main():
     #  how to warp them all the way down to the image level.)
     dset = kwcoco.CocoDataset(filepath_to_images)
 
-    assert dset.n_videos == 1, 'only handling 1 video for now'
+    assert dset.n_videos == 1, "only handling 1 video for now"
 
     video_obj = list(dset.videos().objs)[0]
     video_image_ids = dset.images(video_id=video_obj["id"])
 
-    video_space_gsd = util_resolution.ResolvedUnit.coerce(str(video_obj['target_gsd']) + ' mGSD')
+    video_space_gsd = util_resolution.ResolvedUnit.coerce(
+        str(video_obj["target_gsd"]) + " mGSD"
+    )
 
     # Convert the size prior to video space
     vidspace_size_prior = size_prior.at_resolution(video_space_gsd)
     prior_width, prior_height = vidspace_size_prior.window
 
-    region_points_gdf_vidspace, warp_vid_from_wld, region_gdf_utm, region_gdf_crs84 = get_points(
-        video_obj, filepath_to_points
-    )
+    (
+        region_points_gdf_vidspace,
+        warp_vid_from_wld,
+        region_gdf_utm,
+        region_gdf_crs84,
+    ) = get_points(video_obj, filepath_to_points)
     if method == "box":
         polygons = kwimage.Boxes(
             [[p.x, p.y, prior_width, prior_height] for p in region_points_gdf_vidspace],
@@ -461,9 +472,9 @@ def main():
             # Note that each point is associated with a date, so not all the
             # points warped here are actually associated with this image.
             warp_img_from_vid = coco_image.warp_img_from_vid
-            #region_points_gdf_imgspace = region_points_gdf_vidspace.affine_transform(
-             #   warp_img_from_vid.to_shapely()
-            #)
+            # region_points_gdf_imgspace = region_points_gdf_vidspace.affine_transform(
+            #   warp_img_from_vid.to_shapely()
+            # )
 
             delayed_img = coco_image.imdelay("red|green|blue", space="video")
             imdata = delayed_img.finalize()
@@ -478,8 +489,7 @@ def main():
             img = kwimage.ensure_uint255(img)
             predictor.set_image(img, "RGB")
             regions = kwimage.Boxes(
-                [[p.x, p.y, box_width, box_height]
-                 for p in region_points_gdf_vidspace],
+                [[p.x, p.y, box_width, box_height] for p in region_points_gdf_vidspace],
                 "cxywh",
             )
             regions = regions.to_ltrb()
@@ -487,8 +497,8 @@ def main():
             for count_individual_mask, (point, box) in enumerate(
                 zip(region_points_gdf_vidspace, regions)
             ):
-                #if count_individual_mask >10:
-                 #   break
+                # if count_individual_mask >10:
+                #   break
                 masks, scores, logits = predictor.predict(
                     point_coords=np.array([[point.x, point.y]]),
                     point_labels=np.array([1]),
@@ -505,7 +515,7 @@ def main():
 
             # filename = f"{count}_sam_image_mask.png"
             # data = image_predicted(im,geo_polygons_image,filename)
-            #count = count + 1
+            # count = count + 1
         # geo_masks_total=np.reshape(geo_masks_total,(image_id+1,len(region_points_gdf_imgspace)))
         all_predicted_regions /= len(video_image_ids)
         polygons = list(
@@ -525,7 +535,7 @@ def main():
         region_gdf_crs84,
         time_prior,
     )
-    print(f'Writing output to {output}')
+    print(f"Writing output to {output}")
     output.write_text(result.dumps())
 
 
-- 
GitLab


From 1cd8afe5ca572c4278198dc77c7c0d43d7a81730 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Wed, 17 Apr 2024 17:04:06 -0400
Subject: [PATCH 7/8] Fix linter

---
 geowatch/tasks/poly_from_point/predict.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index 4809fd06c..8a2ba283b 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -471,7 +471,7 @@ def main():
             # Get the transform from video space to image space
             # Note that each point is associated with a date, so not all the
             # points warped here are actually associated with this image.
-            warp_img_from_vid = coco_image.warp_img_from_vid
+            # warp_img_from_vid = coco_image.warp_img_from_vid
             # region_points_gdf_imgspace = region_points_gdf_vidspace.affine_transform(
             #   warp_img_from_vid.to_shapely()
             # )
@@ -489,7 +489,7 @@ def main():
             img = kwimage.ensure_uint255(img)
             predictor.set_image(img, "RGB")
             regions = kwimage.Boxes(
-                [[p.x, p.y, box_width, box_height] for p in region_points_gdf_vidspace],
+                [[p.x, p.y, prior_width, prior_height] for p in region_points_gdf_vidspace],
                 "cxywh",
             )
             regions = regions.to_ltrb()
-- 
GitLab


From 6dd75d97152c5660ecc7e2cadfb785c7aed0e9f7 Mon Sep 17 00:00:00 2001
From: joncrall <jon.crall@kitware.com>
Date: Thu, 18 Apr 2024 12:10:17 -0400
Subject: [PATCH 8/8] More flexible video space

---
 geowatch/tasks/poly_from_point/predict.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/geowatch/tasks/poly_from_point/predict.py b/geowatch/tasks/poly_from_point/predict.py
index 8a2ba283b..2e30e9bc6 100644
--- a/geowatch/tasks/poly_from_point/predict.py
+++ b/geowatch/tasks/poly_from_point/predict.py
@@ -428,8 +428,7 @@ def main():
     video_image_ids = dset.images(video_id=video_obj["id"])
 
     video_space_gsd = util_resolution.ResolvedUnit.coerce(
-        str(video_obj["target_gsd"]) + " mGSD"
-    )
+        video_obj["target_gsd"], default_unit='mGSD')
 
     # Convert the size prior to video space
     vidspace_size_prior = size_prior.at_resolution(video_space_gsd)
-- 
GitLab