WongKinYiu / yolor

implementation of paper - You Only Learn One Representation: Unified Network for Multiple Tasks (https://arxiv.org/abs/2105.04206)
GNU General Public License v3.0
1.98k stars 524 forks source link

IoU calculation error? (for confusion matrix) #236

Open Swearinbag opened 2 years ago

Swearinbag commented 2 years ago

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]

weitsung50110 commented 2 years ago

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

Swearinbag commented 1 year ago

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!

WongKinYiu commented 1 year ago

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

Swearinbag commented 1 year ago

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.