2

I am training yolov5 on my custom dataset and am getting the non-normalized labels' error. The annotations have x,y, and w,h which means that the bounding box is present from (x,y) to (x+w,y+h). I am using the cv2 rectangle function to display the bounding boxes on the image and it is creating the perfect bounding boxes. I understand that I have to convert my raw labels to normalized center x, center y, width, and height values. I am doing that below:

x2=x+w # x,y, w and h are given
y2=y1+h

xc=x+w/2
yc=y+h/2
xc=xc/width # normalize from 0-1. Width and height are image's width and height
yc=yc/height
  
wn=w/width # normalize the width from 0-1
hn=h/height
 
label_file.write(f"{category_idx} {xc} {yc} {wn} {hn}\n")

But when I write these labels in the text file and run the yolov5 training, it gives the following assertion error:

assert (l[:, 1:] <= 1).all(), 'non-normalized or out of bounds coordinate labels: %s' % file # throws assertion error
AssertionError: non-normalized or out of bounds coordinate labels: /Raja/Desktop/yolov5/data/roi/labels/train/10.txt

The 10.txt file is given below:

1 0.7504960317460317 0.3599537037037037 0.16765873015873023 0.059193121693121686
4 0.21664186507936506 0.3316798941798942 0.19122023809523808 0.0443121693121693
5 0.47879464285714285 0.2931547619047619 0.32663690476190477 0.04728835978835977
0 0.265625 0.47701719576719576 0.3045634920634921 0.0889550264550264
1 0.17671130952380953 0.5830026455026455 0.13120039682539683 0.07275132275132279
2 0.5212053571428572 0.7986111111111112 0.15550595238095244 0.07407407407407407
2 0.7638888888888888 0.8009259259259259 0.16121031746031755 0.07275132275132279

I am using the cv2 rectangle function to display the bounding boxes on the image and it is creating the perfect bounding boxes as displayed in the picture below:

cv2.rectangle(temp_img,(int(x), int(y)),(int(x+w), int(y+h)),color=(0, 255, 0),thickness=2)

bounding boxes created properly on the image

I have tried to find the solution online like from this issue raised on GitHub but haven't found anything yet. Can anyone please tell me what am I doing wrong here? I believe that the issue exists in converting raw labels to 0-1 normalized labels as the assertion states that it has found non-normalized labels. Any help will be highly appreciated!

Asim
  • 1,430
  • 1
  • 22
  • 43
  • Can you check that no bb position is out of image bounds? – Micka Mar 24 '22 at 16:06
  • yes, I have drawn them manually on the image. I commented out the assert line and committed those images from the dataset. Yolov5 gave non-normalized error for all the images. – Asim Mar 24 '22 at 16:34
  • Can you upload the 10.txt file? Did you check for stuff like empty rows etc.? – Micka Mar 24 '22 at 21:58
  • @Micka I have edited the question. Can you please check now? yes, there are no empty rows. I am getting the same error for "all" the label files. – Asim Mar 24 '22 at 22:08

1 Answers1

6

YOLOv5 requires the dataset to be in the darknet format. Here’s an outline of what it looks like:

  • One txt with labels file per image
  • One row per object
  • Each row is class x_center y_center width height format.
  • Box coordinates must be in normalized xywh format (from 0 - 1). If your boxes are in pixels, divide x_center and width by image width, and y_center and height by image height.
  • Class numbers are zero-indexed (start from 0).

Example:

  • Image properties: width=1156 pix, height=1144 pix.
  • bounding box properties: xmin=1032, ymin=20, xmax=1122, ymax=54, object_name="Ring".
  • Let objects_list="bracelet","Earring","Ring","Necklace"

YOLOv5 format: f"{category_idx} {x1 + bbox_width / 2} {y1 + bbox_height / 2} {bbox_width} {bbox_height}\n"

  • $bbox_{width} = x_{max}/width - x_{min}/width = (1122-1032)/1156 = 0.07785467128027679$
  • $bbox_{height} = y_{max}/height - y_{min}/height = (54-20)/1144 = 0.029720279720279717$
  • $x_{center}=x_{min}/width+bbox_{width}/2 = 0.9316608996539792$
  • $y_{center}=y_{min}/height + bbox_{height}/2 = 0.032342657342657344$
  • category_idx=2
  • Final result: 2 0.9316608996539792 0.032342657342657344 0.07785467128027679 0.029720279720279717
Illustrati
  • 311
  • 1
  • 9
  • thank you...but in my case, I have x,y, w, and h. So, will x_min=x and x_max=x+w for me? and similarly for y. – Asim Mar 24 '22 at 09:42
  • I have tried your code and it is giving the same error. I used x_max=x+w and y_max=y+h. x_min=x and y_min=y. – Asim Mar 24 '22 at 11:37
  • Please reread my answer. According to your description, w and h represent the bounding box dimensions. Nevertheless, you are not considering the total image width and height. X_min and y_min correspond to the lowest corner of your bounding box. Once you take the image properties into account, you will see the normalized x_center and y_center. – Illustrati Mar 25 '22 at 06:10
  • I am taking the image's width and height into consideration. I have edited my answer for more charity. Can you please check again? I am using your exact solution but am still getting the same error. – Asim Mar 25 '22 at 08:55
  • Your data looks fine. I mean, it's already normalized. You must report this issue in https://github.com/ultralytics/yolov5/issues. BTW, did you try using OCR instead of YOLO? It seems that you can complete your duty with more straightforward solutions. – Illustrati Mar 27 '22 at 07:31
  • Did you try reinstalling yolov5? You can delete your current folder and download it again; follow the official guidelines. Don't forget to save any valuable training data from the folder 'runs.' – Illustrati Mar 27 '22 at 07:35
  • I have opened an issue at github here https://github.com/ultralytics/yolov5/issues/7135. You are more than welcome to comment there your findings. I used OCR but it was extracting all the unnecessary text as well which was difficult to post-process. – Asim Mar 27 '22 at 09:52