davisking / dlib

A toolkit for making real world machine learning and data analysis applications in C++
http://dlib.net
Boost Software License 1.0
13.53k stars 3.37k forks source link

[Bug]: simple_object_detector throws error for aspect ratio mismatch even when all bounding boxes are of the same dimension #2824

Open tintin-py opened 1 year ago

tintin-py commented 1 year ago

What Operating System(s) are you seeing this problem on?

Windows

dlib version

19.24.99

Python version

3.9.13

Compiler

GCC 6.3.0

Expected Behavior

I should not get aspect ratio error while running the dlib simple_object_detector on images with exactly same bounding box dimensions. A sample of the training.xml file is given below.

`

imglab dataset Created by imglab tool. ......` ### Current Behavior Even though all the dimensions are equal I still get the error thrown for aspect ratio mismatch in marked bounding boxes. The error based on the code below is showing this. Training with C: 1 Training with epsilon: 0.01 Training using 4 threads. Training with sliding window 302 pixels wide by 21 pixels tall. Upsample images... Upsample images... #################### Error in labelling #################### Adjusting bounding boxes to have same dimensions i.e. same aspect ratio Auxilliary training file created: C:\Users\Pratyay Mukherjee\Desktop\IIT Bombay - MTech\ToyoProject+Seminar\PhaseA\demo_line_number_extraction\ARAMCO_TRAIN\aux_training.xml Training with C: 1 Training with epsilon: 0.01 Training using 4 threads. Training with sliding window 284 pixels wide by 23 pixels tall. Upsample images... Upsample images... Traceback (most recent call last): File "C:\Users\Pratyay Mukherjee\Desktop\IIT Bombay - MTech\ToyoProject+Seminar\PhaseA\svm_object_detector_train.py", line 64, in main dlib.train_simple_object_detector(training_file, model_path, options) RuntimeError: Error! An impossible set of object boxes was given for training. All the boxes need to have a similar aspect ratio and also not be smaller than about 400 pixels in area. The following images contain invalid boxes: patches\0.jpg patches\11.jpg patches\4.jpg patches\5.jpg patches\9.jpg During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Pratyay Mukherjee\Desktop\IIT Bombay - MTech\ToyoProject+Seminar\PhaseA\svm_object_detector_train.py", line 84, in main(args) File "C:\Users\Pratyay Mukherjee\Desktop\IIT Bombay - MTech\ToyoProject+Seminar\PhaseA\svm_object_detector_train.py", line 69, in main dlib.train_simple_object_detector(aux_training_file, model_path, options) RuntimeError: Error! An impossible set of object boxes was given for training. All the boxes need to have a similar aspect ratio and also not be smaller than about 400 pixels in area. The following images contain invalid boxes: patches\0.jpg patches\10.jpg patches\11.jpg patches\4.jpg patches\5.jpg ### Steps to Reproduce The options are as follows ` options = dlib.simple_object_detector_training_options() options.add_left_right_image_flips = bool(flip) #False options.C = svmC #1 options.num_threads = 4 options.be_verbose = True` The up-sample limit is by default 2. The value of the variable assignments to the options is given in the comments. ### Anything else? I am attaching the code here for reference. ``` import dlib import os import argparse import xml.etree.ElementTree as ET #replace the curret bounding boxes with the maximum dimensions in all the dataset #parses the tree and sets the dimensions required #returns the path of the new XML file saved def adjust_bounding_boxes(xml_file): tree = ET.parse(xml_file) root = tree.getroot() #compute max width and height images = root.find('images') img_lst = images.findall('image') width_lst, height_lst = [], [] for img in img_lst: box_lst = img.findall('box') for box in box_lst: width_lst.append(int(box.get('width'))) height_lst.append(int(box.get('height'))) maxWidth, maxHeight = max(width_lst), max(height_lst) #set the new dimensions for img in img_lst: box_lst = img.findall('box') for box in box_lst: box.set('width', str(maxWidth)) box.set('height', str(maxHeight)) #write the new training file save_file_path = os.path.join(os.path.split(xml_file)[0], 'aux_training.xml') print(f"Auxilliary training file created: {save_file_path}") tree.write(save_file_path) return save_file_path def main(args): #training and testing xml files training_file = args.train model_path = args.model svmC = float(args.svmC) flip = int(args.flip) #check on xml file paths assert os.path.exists(training_file) and os.path.isfile(training_file), "training.xml path does not exist or is not a file" #setup training configuration options = dlib.simple_object_detector_training_options() options.add_left_right_image_flips = bool(flip) options.C = svmC options.num_threads = 4 options.be_verbose = True #training try: dlib.train_simple_object_detector(training_file, model_path, options) except Exception as e: print(f"#################### Error in labelling ####################") print(" Adjusting bounding boxes to have same dimensions i.e. same aspect ratio") aux_training_file = adjust_bounding_boxes(training_file) dlib.train_simple_object_detector(aux_training_file, model_path, options) #training and testing accuracy scores print("Training accuracy: {}".format(dlib.test_simple_object_detector(training_file, model_path))) ```
davisking commented 1 year ago

Can you post a complete working example? One we could run to see what happens?