yolor icon indicating copy to clipboard operation
yolor copied to clipboard

IoU calculation error? (for confusion matrix)

Open Swearinbag opened this issue 2 years ago • 4 comments

I've been trying to implement a correct confusion matrix with a selfmade IoU calculation and such but, since I'm doing the same your algorithm does in utils.general.box_iou, I'm still getting different results when comparing the end result of what the script prints when detect.py is run. The following is how I do it, after I've converted the tensor variables to just a numpy array and feed them one by one in the following function:

def getIoU(boxA,boxB):
    #boxA: x1,y1,x2,y2
    #boxB: x1,y1,x2,y2
    xA = max(boxA[0], boxB[0])
    yA = max(boxA[1], boxB[1])
    xB = min(boxA[2], boxB[2])
    yB = min(boxA[3], boxB[3])
 
    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)
 
    boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
    boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)
 
    iou = interArea / float(boxAArea + boxBArea - interArea)
 
    return iou

Then I use this function in the following function to create my confusion matrix:

def createConfMat(preds,labs,names,IoUtresh = 0.45,conftresh=0.5,exclude=1):
    #preds: (Array[N, 6]): x1, y1, x2, y2, conf, class    
    #labs:  (Array[M, 5]): class, x1, y1, x2, y2
    vals = []
    for pred in preds:
        for lab in labs:
            IoU = getIoU(pred[0:4],lab[1:])
            if(IoU >= IoUtresh):
                if (pred[4] >= conftresh) and (exclude == 1):
                    vals.append([pred[-1],lab[0]]) #pred/lab class pair into vals
                elif exclude == 0:
                    vals.append([pred[-1],lab[0]])
                else:
                    pass
    n = len(names)
    result = np.zeros((n,n))
    for i in range(len(vals)):
        p = int(vals[i][1])
        l = int(vals[i][0])
        result[p][l] += 1
 
    return result

With this function I then use preds,labs,names,IoUtresh,conftresh from the variables in detects.py and the exclude is just so the values that don't fit the treshold are not printed (for comparison with every label vs only confident labels). I call the function above as seen below, with detects and labs being predicitons and labels respectively, converted to a list of lists.

createConfMat(np.array(detects),np.array(labs),names,exclude=0,conftresh=opt.conf_thres,IoUtresh=opt.iou_thres)

The result when printing this confusion matrix is the following: image

It's clear that some classes seemingly disappear in my confusion matrix, but I have no idea why. I'm seemingly following the correct (?) steps. Can someone assist me? :)

ps: structure of classes is the following: [capacitor,chips,crystal,diode,inductor,resistor,transistor]

Swearinbag avatar May 18 '22 10:05 Swearinbag

How can you get the files which were labeled in detect.py?

weitsung50110 avatar Jun 22 '22 18:06 weitsung50110

I used a global variable to accumulate everything into a list of detections. I then added the files by appending it when the loop goes over the files.

Could you specify what issue that you have? sorry for the delayed reply!

Swearinbag avatar Aug 11 '22 21:08 Swearinbag

Have you checked your bbox format is cxcywh or xyxy or another format?

WongKinYiu avatar Aug 12 '22 01:08 WongKinYiu

I have indeed checked the format before- but I've actually did it another way. I finished my work with YOLOR atm, so this thread can be closed if Weitsung50110 doesn't reply soon.

Swearinbag avatar Aug 13 '22 18:08 Swearinbag