dlib icon indicating copy to clipboard operation
dlib copied to clipboard

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

Open tintin-py opened this issue 2 years ago • 1 comments

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 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)))

tintin-py avatar Jul 12 '23 07:07 tintin-py

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

davisking avatar Jul 16 '23 13:07 davisking