dlib
                                
                                 dlib copied to clipboard
                                
                                    dlib copied to clipboard
                            
                            
                            
                        [Bug]: simple_object_detector throws error for aspect ratio mismatch even when all bounding boxes are of the same dimension
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.
<dataset> <name>imglab dataset</name> <comment>Created by imglab tool.</comment> <images> <image file="patches\0.jpg" width="4962" height="3508"> <box top="1992" left="932" width="771" height="61" /> <box top="500" left="1166" width="771" height="61" /> <box top="3299" left="2296" width="771" height="61" /> <box top="2514" left="926" width="771" height="61" /> <box top="2752" left="926" width="771" height="61" /> <box top="652" left="514" width="771" height="61" /> <box top="1858" left="1440" width="771" height="61" /> </image> <image file="patches\10.jpg" width="4962" height="3509"> <box top="1281" left="2728" width="771" height="61" /> <box top="2380" left="717" width="771" height="61" /> <box top="2177" left="2456" width="771" height="61" /> </image>......
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 
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)))
Can you post a complete working example? One we could run to see what happens?