@@ -146,6 +146,65 @@ def test_coco_with_subdir_file_name_should_match_annotations(self):
146146 # Expect annotationfile to be populated, but this currently fails due to basename-only matching
147147 self .assertIsNotNone (img_entry .get ("annotationfile" ))
148148
149+ def test_coco_root_annotation_matches_images_in_subdirs (self ):
150+ """Test that COCO annotation at root can match images in subdirectories.
151+
152+ This tests the fix for the bug where annotation file dirname (/) didn't match
153+ image dirname (/1/100001), causing annotations to not be found.
154+ """
155+ with tempfile .TemporaryDirectory () as tmpdir :
156+ # Create image in subdirectory
157+ subdir = os .path .join (tmpdir , "1" , "100001" )
158+ os .makedirs (subdir , exist_ok = True )
159+ image_name = "image.jpeg"
160+ image_path = os .path .join (subdir , image_name )
161+ open (image_path , "wb" ).close ()
162+
163+ # Create COCO annotation at root referencing image with subdirectory path
164+ coco = {
165+ "info" : {},
166+ "licenses" : [],
167+ "categories" : [{"id" : 1 , "name" : "object" }],
168+ "images" : [
169+ {
170+ "id" : 10000000 ,
171+ "file_name" : "1/100001/image.jpeg" ,
172+ "width" : 800 ,
173+ "height" : 600 ,
174+ }
175+ ],
176+ "annotations" : [
177+ {
178+ "id" : 1 ,
179+ "image_id" : 10000000 ,
180+ "category_id" : 1 ,
181+ "bbox" : [10 , 20 , 100 , 200 ],
182+ "area" : 20000 ,
183+ "segmentation" : [[10 , 20 , 110 , 20 , 110 , 220 , 10 , 220 ]],
184+ "iscrowd" : 0 ,
185+ }
186+ ],
187+ }
188+ coco_path = os .path .join (tmpdir , "_annotations.coco.json" )
189+ with open (coco_path , "w" ) as f :
190+ json .dump (coco , f )
191+
192+ parsed = folderparser .parsefolder (tmpdir )
193+
194+ # Find the image
195+ img_entries = [i for i in parsed ["images" ] if image_name in i ["file" ]]
196+ self .assertEqual (len (img_entries ), 1 , "Should find exactly one image" )
197+ img_entry = img_entries [0 ]
198+
199+ # Verify annotation was matched
200+ self .assertIsNotNone (img_entry .get ("annotationfile" ), "Image should have annotation" )
201+
202+ # Verify annotation content
203+ ann_data = json .loads (img_entry ["annotationfile" ]["rawText" ])
204+ self .assertEqual (len (ann_data ["images" ]), 1 , "Should have one image reference" )
205+ self .assertEqual (len (ann_data ["annotations" ]), 1 , "Should have one annotation" )
206+ self .assertEqual (ann_data ["annotations" ][0 ]["bbox" ], [10 , 20 , 100 , 200 ])
207+
149208
150209def _assertJsonMatchesFile (actual , filename ):
151210 with open (filename ) as file :
0 commit comments