1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ # Copyright 2025 The TensorFlow Authors. All Rights Reserved.
16+ #
17+ # Licensed under the Apache License, Version 2.0 (the "License");
18+ # you may not use this file except in compliance with the License.
19+ # You may obtain a copy of the License at
20+ #
21+ # http://www.apache.org/licenses/LICENSE-2.0
22+ #
23+ # Unless required by applicable law or agreed to in writing, software
24+ # distributed under the License is distributed on an "AS IS" BASIS,
25+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26+ # See the License for the specific language governing permissions and
27+ # limitations under the License.
28+
1529"""Detects, segments, and saves objects from images in a directory.
1630
1731This script initializes a computer vision pipeline to process images, identify
3751warnings .filterwarnings ("ignore" , category = FutureWarning )
3852warnings .filterwarnings ("ignore" , category = UserWarning )
3953
40- # Path to the pre-trained weights for the Grounding DINO model.
54+
4155GROUNDING_DINO_WEIGHTS = (
4256 "milk_pouch_project/grounding_dino_model/groundingdino_swint_ogc.pth"
4357)
44-
45- # Path to the configuration file for the Grounding DINO model.
4658GROUNDING_DINO_CONFIG = (
4759 "milk_pouch_project/grounding_dino_model/GroundingDINO_SwinT_OGC.py"
4860)
49-
50- # Path to the pre-trained weights for the SAM2 model.
5161SAM2_WEIGHTS = "milk_pouch_project/sam2_model/sam2.1_hiera_large.pt"
52-
53- # Path to the configuration file for the SAM2 model.
5462SAM2_CONFIG = "configs/sam2.1/sam2.1_hiera_l.yaml"
55-
56- # Text prompt to use for object detection.
5763TEXT_PROMPT = "packets"
58-
59- # Name of the temporary directory to store cropped object images.
60- TEMP_DIR = "tempdir"
61-
62- # Path to save the output COCO dataset file.
64+ INPUT_DIR = "input_images"
65+ CLASSIFICATION_DIR = "objects_for_classification"
6366COCO_OUTPUT_PATH = "coco_output.json"
6467
6568# Minimum mask area as percentage of image.
6669MIN_MASK_AREA_PERCENT = 1.0
6770
6871FLAGS = flags .FLAGS
69- flags .DEFINE_string (
70- "input_dir" ,
71- None ,
72- "Directory containing image frames to process." ,
73- required = True ,
74- )
7572flags .DEFINE_string (
7673 "category_name" ,
7774 None ,
8178
8279def main (_ ) -> None :
8380 """Runs the main object detection and extraction pipeline."""
84- if not os .path .isdir (FLAGS . input_dir ):
85- raise ValueError (f"Input directory not found at '{ FLAGS . input_dir } '" )
81+ if not os .path .isdir (INPUT_DIR ):
82+ raise ValueError (f"Input directory not found at '{ INPUT_DIR } '" )
8683
8784 # Check if COCO output should be created
8885 create_coco = FLAGS .category_name is not None
8986
90- print ("Initializing Vision and Llm Pipeline ..." )
87+ print ("Initializing image extraction and classification ..." )
9188 try :
9289 pipeline = models .ObjectDetectionSegmentation (
9390 dino_config_path = GROUNDING_DINO_CONFIG ,
@@ -104,7 +101,7 @@ def main(_) -> None:
104101 print ("✅ Pipeline ready." )
105102
106103 # Create output directory
107- output_dir = os .path .join (FLAGS . input_dir , TEMP_DIR )
104+ output_dir = os .path .join (INPUT_DIR , CLASSIFICATION_DIR )
108105 os .makedirs (output_dir , exist_ok = True )
109106
110107 # Initialize coco json file format only if category_name is provided
@@ -119,7 +116,7 @@ def main(_) -> None:
119116 print ("No category name provided. Skipping COCO JSON creation." )
120117
121118 # Get all image files.
122- all_files = glob .glob (os .path .join (FLAGS . input_dir , "*" ))
119+ all_files = glob .glob (os .path .join (INPUT_DIR , "*" ))
123120 image_extensions = (".jpg" , ".jpeg" , ".png" , ".bmp" )
124121 files = [f for f in all_files if f .lower ().endswith (image_extensions )]
125122 files = natsort .natsorted (files )
@@ -141,12 +138,6 @@ def main(_) -> None:
141138 )
142139 continue
143140
144- # Uncomment to filter bigger overlapping boxes.
145- # filtered_results = pipeline.filter_boxes_keep_smaller(
146- # results,
147- # iou_threshold=0.95
148- # )
149-
150141 image = results ["image" ]
151142 h , w = image .shape [:2 ]
152143 image_area = h * w
@@ -169,7 +160,7 @@ def main(_) -> None:
169160 try :
170161 masked_object = models_utils .extract_masked_object (image , mask , box )
171162 models_utils .save_masked_object (
172- masked_object , file_path , idx , TEMP_DIR
163+ masked_object , file_path , idx , CLASSIFICATION_DIR
173164 )
174165 except (ValueError , SystemError , AttributeError , OSError ) as e :
175166 print (
@@ -180,10 +171,7 @@ def main(_) -> None:
180171
181172 # Add annotation info to COCO output only if create_coco is True
182173 if create_coco :
183- # Get the polygon points of masks.
184174 segmentation = models_utils .extract_largest_contour_segmentation (mask )
185-
186- # coco bbox format
187175 bbox_width , bbox_height , area = models_utils .get_bbox_details (box )
188176
189177 # annotation key format in coco json
@@ -199,20 +187,18 @@ def main(_) -> None:
199187 ],
200188 "area" : int (area ),
201189 "iscrowd" : 0 ,
202- "segmentation" : (
203- segmentation
204- ), # Optional: Add segmentation if you have it
190+ "segmentation" : segmentation ,
205191 }
206192 coco_output ["annotations" ].append (annotation_info )
207193 annotation_id_counter += 1
208194
209195 # Save COCO JSON file only if create_coco is True
210196 if create_coco :
211- with open (os .path .join (FLAGS . input_dir , COCO_OUTPUT_PATH ), "w" ) as f :
197+ with open (os .path .join (INPUT_DIR , COCO_OUTPUT_PATH ), "w" ) as f :
212198 json .dump (coco_output , f , indent = 4 )
213199 print (f"\n ✅ Processing complete. COCO JSON saved to '{ COCO_OUTPUT_PATH } '." )
214200
215- print (f"✅ Cropped images saved to '{ TEMP_DIR } '." )
201+ print (f"✅ Cropped images saved to '{ CLASSIFICATION_DIR } '." )
216202
217203
218204if __name__ == "__main__" :
0 commit comments