box

nms_comparator

int nms_comparator(const void *pa, const void *pb)
{
    detection a = *(detection *)pa;
    detection b = *(detection *)pb;
    float diff = 0;
    if(b.sort_class >= 0){
        diff = a.prob[b.sort_class] - b.prob[b.sort_class];
    } else {
        diff = a.objectness - b.objectness;
    }
    if(diff < 0) return 1;
    else if(diff > 0) return -1;
    return 0;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: nms_comparator

์ž…๋ ฅ:

  • void ํฌ์ธํ„ฐํ˜• pa

  • void ํฌ์ธํ„ฐํ˜• pb

๋™์ž‘:

  • pa์™€ pb๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” detection ๊ตฌ์กฐ์ฒด a์™€ b๋ฅผ ๊ฐ€์ ธ์™€, a์™€ b์˜ ํ™•๋ฅ (prob)์ด๋‚˜ ๊ฐœ์ฒด(objectness)์˜ ์ฐจ์ด(diff)๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.

  • sort_class๊ฐ€ 0๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” prob์˜ ์ฐจ์ด๋ฅผ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” objectness์˜ ์ฐจ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •๋ ฌํ•œ๋‹ค.

์„ค๋ช…:

  • Non-Maximum Suppression(NMS) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ comparator ํ•จ์ˆ˜์ด๋‹ค.

  • NMS๋Š” ๊ฐ์ฒด ํƒ์ง€(Object Detection)์—์„œ ์ค‘๋ณต๋˜๋Š” ๋ฐ•์Šค(Box)๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

  • NMS๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ „์—, ๊ฐ์ฒด ๊ฒ€์ถœ ๋ชจ๋ธ์ด ์˜ˆ์ธกํ•œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐ•์Šค๋“ค์„ ํ™•๋ฅ  ๋“ฑ์˜ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š”๋ฐ, ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

  • a์™€ b๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” detection ๊ตฌ์กฐ์ฒด์˜ ์š”์†Œ ์ค‘ sort_class๋ฒˆ์งธ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ™•๋ฅ (prob) ํ˜น์€ ๊ฐœ์ฒด(objectness)์˜ ์ฐจ์ด(diff)๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์ •๋ ฌํ•œ๋‹ค.

  • ํ•จ์ˆ˜ ๋‚ด์—์„œ qsort() ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

do_nms_obj

void do_nms_obj(detection *dets, int total, int classes, float thresh)
{
    int i, j, k;
    k = total-1;
    for(i = 0; i <= k; ++i){
        if(dets[i].objectness == 0){
            detection swap = dets[i];
            dets[i] = dets[k];
            dets[k] = swap;
            --k;
            --i;
        }
    }
    total = k+1;

    for(i = 0; i < total; ++i){
        dets[i].sort_class = -1;
    }

    qsort(dets, total, sizeof(detection), nms_comparator);
    for(i = 0; i < total; ++i){
        if(dets[i].objectness == 0) continue;
        box a = dets[i].bbox;
        for(j = i+1; j < total; ++j){
            if(dets[j].objectness == 0) continue;
            box b = dets[j].bbox;
            if (box_iou(a, b) > thresh){
                dets[j].objectness = 0;
                for(k = 0; k < classes; ++k){
                    dets[j].prob[k] = 0;
                }
            }
        }
    }
}

ํ•จ์ˆ˜ ์ด๋ฆ„: do_nms_obj

์ž…๋ ฅ:

  • detection *dets: detection ๊ตฌ์กฐ์ฒด ๋ฐฐ์—ด ํฌ์ธํ„ฐ

  • int total: detection ๋ฐฐ์—ด์˜ ์ด ์›์†Œ ๊ฐœ์ˆ˜

  • int classes: ๋ถ„๋ฅ˜(classification) ์ˆ˜

  • float thresh: IOU(Intersection over Union) ์ž„๊ณ„๊ฐ’

๋™์ž‘:

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ detection ๋ฐฐ์—ด์—์„œ objectness๊ฐ€ 0์ธ detection์„ ๋ฐฐ์—ด์˜ ๋์œผ๋กœ ์ด๋™์‹œํ‚ค๊ณ  ํ•ด๋‹น ์›์†Œ๋ฅผ ๋ฐฐ์—ด์—์„œ ์ œ๊ฑฐํ•จ

  • ์ •๋ ฌ๋˜์ง€ ์•Š์€ detection ๋ฐฐ์—ด์„ class์˜ ํ™•๋ฅ ๊ฐ’(prob) ๋˜๋Š” objectness ๊ฐ’(objectness)์„ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ

  • ์ •๋ ฌ๋œ detection ๋ฐฐ์—ด์—์„œ IOU๊ฐ€ ์ž„๊ณ„๊ฐ’(thresh) ์ด์ƒ์ธ detection ์Œ์„ ์ฐพ์•„์„œ ๋‚ฎ์€ objectness ๊ฐ’๊ณผ ํ•ด๋‹น ์Œ์˜ ๋ชจ๋“  class์˜ ํ™•๋ฅ ๊ฐ’์„ 0์œผ๋กœ ์„ค์ •ํ•จ

์„ค๋ช…:

  • non-maximum suppression(NMS) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋กœ, ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ detection ๋ฐฐ์—ด์—์„œ ๊ฒน์น˜๋Š” ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ์—ญํ• ์„ ํ•จ

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ detection ๊ตฌ์กฐ์ฒด ๋ฐฐ์—ด ํฌ์ธํ„ฐ(dets)๋Š” ๋ฐ•์Šค(bounding box)์˜ ์œ„์น˜, ํฌ๊ธฐ, confidence(ํ™•๋ฅ ), class ํ™•๋ฅ  ๋“ฑ์„ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ์ฒด ๋ฐฐ์—ด์ž„

  • ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฒ€์ถœํ•œ detection ๊ตฌ์กฐ์ฒด ๋ฐฐ์—ด(dets)์„ objectness ๊ฐ’์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ณ , ๊ฒน์น˜๋Š” ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•จ

  • ๊ฐ์ฒด๋ฅผ ๊ฒ€์ถœํ•œ detection ๋ฐฐ์—ด์—์„œ objectness๊ฐ€ 0์ธ detection์„ ์ œ๊ฑฐํ•จ์œผ๋กœ์จ, ๊ฒน์น˜๋Š” ๋ฐ•์Šค ์ค‘์—์„œ objectness ๊ฐ’์ด ๋‚ฎ์€ ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•จ

  • objectness๊ฐ€ 0์ด ๋˜๋ฉด ํ•ด๋‹น ๋ฐ•์Šค๋Š” ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ•˜๊ณ , ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” class ํ™•๋ฅ ๊ฐ’์„ 0์œผ๋กœ ์„ค์ •ํ•จ

  • ์ด๋Ÿฌํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๊ฑฐ์นœ detection ๋ฐฐ์—ด์€ ์ตœ์ข…์ ์œผ๋กœ ๊ฒน์น˜๋Š” ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•œ ํ›„์˜ ๊ฐ์ฒด ๊ฒ€์ถœ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋ƒ„

do_nms_sort

void do_nms_sort(detection *dets, int total, int classes, float thresh)
{
    int i, j, k;
    k = total-1;
    for(i = 0; i <= k; ++i){
        if(dets[i].objectness == 0){
            detection swap = dets[i];
            dets[i] = dets[k];
            dets[k] = swap;
            --k;
            --i;
        }
    }
    total = k+1;

    for(k = 0; k < classes; ++k){
        for(i = 0; i < total; ++i){
            dets[i].sort_class = k;
        }
        qsort(dets, total, sizeof(detection), nms_comparator);
        for(i = 0; i < total; ++i){
            if(dets[i].prob[k] == 0) continue;
            box a = dets[i].bbox;
            for(j = i+1; j < total; ++j){
                box b = dets[j].bbox;
                if (box_iou(a, b) > thresh){
                    dets[j].prob[k] = 0;
                }
            }
        }
    }
}

ํ•จ์ˆ˜ ์ด๋ฆ„: do_nms_sort

์ž…๋ ฅ:

  • detection *dets: ๊ฐ ํด๋ž˜์Šค์˜ detection ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฐฐ์—ด

  • int total: ์ด detection ๊ฐœ์ˆ˜

  • int classes: ํด๋ž˜์Šค ๊ฐœ์ˆ˜

  • float thresh: IoU ์ž„๊ณ„๊ฐ’

๋™์ž‘:

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ detection ๋ฐฐ์—ด์—์„œ objectness ๊ฐ’์ด 0์ธ detection์€ ์ œ๊ฑฐํ•œ๋‹ค.

  • classes ๊ฐœ์ˆ˜๋งŒํผ ๋ฐ˜๋ณตํ•˜๋ฉฐ, ๊ฐ ํด๋ž˜์Šค์— ๋Œ€ํ•œ detection ๊ฒฐ๊ณผ๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.

  • ์ •๋ ฌ๋œ detection ๊ฒฐ๊ณผ ์ค‘, ํ™•๋ฅ ๊ฐ’์ด 0์ธ detection์€ ์ œ์™ธํ•œ๋‹ค.

  • ์ดํ›„, ๊ฐ detection ๊ฒฐ๊ณผ์˜ bounding box์™€ ๋‹ค๋ฅธ detection ๊ฒฐ๊ณผ์˜ bounding box์˜ IoU๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ, ์ž„๊ณ„๊ฐ’(thresh)๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ ํ•ด๋‹น detection์˜ ํ™•๋ฅ ๊ฐ’์„ 0์œผ๋กœ ๋งŒ๋“ ๋‹ค.

์„ค๋ช…:

  • ์ด ํ•จ์ˆ˜๋Š” Object Detection์—์„œ NMS(Non-Maximum Suppression)์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋กœ, ํด๋ž˜์Šค๋ณ„๋กœ detection ๊ฒฐ๊ณผ๋ฅผ ์ •๋ ฌํ•˜์—ฌ IoU ์ž„๊ณ„๊ฐ’์„ ๋„˜๋Š” detection ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

  • ์ด๋ฅผ ํ†ตํ•ด, ๊ฒน์น˜๋Š” ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์ตœ์ข… detection ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ ๋œ๋‹ค.

float_to_box

box float_to_box(float *f, int stride)
{
    box b = {0};
    b.x = f[0];
    b.y = f[1*stride];
    b.w = f[2*stride];
    b.h = f[3*stride];
    return b;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: float_to_box

์ž…๋ ฅ:

  • float *f: 4๊ฐœ์˜ ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ง„ 1์ฐจ์› float ๋ฐฐ์—ด ํฌ์ธํ„ฐ

  • int stride: ๋ฐฐ์—ด์—์„œ ๊ฐ’ ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ

๋™์ž‘:

  • ์ฃผ์–ด์ง„ float ๋ฐฐ์—ด ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด box ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • box ๊ตฌ์กฐ์ฒด๋Š” x, y, w, h ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.

  • x, y, w, h ๊ฐ’์€ ๊ฐ๊ฐ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ, stride ๋ฒˆ์งธ, 2stride ๋ฒˆ์งธ, 3stride ๋ฒˆ์งธ ๊ฐ’์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ์ด ํ•จ์ˆ˜๋Š” ์ฃผ๋กœ YOLO์™€ ๊ฐ™์€ ๊ฐ์ฒด ๊ฒ€์ถœ ๋ชจ๋ธ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • ๊ฐ์ฒด ๊ฒ€์ถœ ๋ชจ๋ธ์€ bounding box๋ฅผ ์ถœ๋ ฅ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ, ์ด bounding box๋Š” (x,y,w,h) ํ˜•ํƒœ์˜ 4๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

  • ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ์ถœ๋ ฅ๊ฐ’์€ float ๋ฐฐ์—ด์˜ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์ ์ ˆํ•œ ํ˜•ํƒœ์˜ ๊ตฌ์กฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • float_to_box ํ•จ์ˆ˜๋Š” ์ด๋Ÿฌํ•œ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

overlap

float overlap(float x1, float w1, float x2, float w2)
{
    float l1 = x1 - w1/2;
    float l2 = x2 - w2/2;
    float left = l1 > l2 ? l1 : l2;
    float r1 = x1 + w1/2;
    float r2 = x2 + w2/2;
    float right = r1 < r2 ? r1 : r2;
    return right - left;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: overlap

์ž…๋ ฅ:

  • ๋„ค ๊ฐœ์˜ ์‹ค์ˆ˜(x1, w1, x2, w2)๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

๋™์ž‘:

  • ๋‘ ๊ฐœ์˜ ๋ฐ•์Šค๊ฐ€ ๊ฒน์น˜๋Š” ์˜์—ญ์˜ ๋„ˆ๋น„๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ•์Šค์˜ ์ค‘์‹ฌ ์ขŒํ‘œ์™€ ํญ์„ ์ด์šฉํ•˜์—ฌ ์™ผ์ชฝ ๋๊ณผ ์˜ค๋ฅธ์ชฝ ๋์„ ๊ณ„์‚ฐํ•œ ๋’ค ๊ฒน์น˜๋Š” ์˜์—ญ์˜ ๋„ˆ๋น„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • Object Detection์—์„œ NMS(Non-Maximum Suppression) ๊ณผ์ •์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • ๋ฐ•์Šค๊ฐ€ ์„œ๋กœ ์–ผ๋งˆ๋‚˜ ๊ฒน์น˜๋Š”์ง€๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ IoU(Intersection over Union) ๊ฐ’์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฒน์น˜๋Š” ์˜์—ญ์ด ์ž‘์„์ˆ˜๋ก IoU ๊ฐ’์€ ์ž‘์•„์ง€๋ฉฐ, ์ผ์ • ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ IoU ๊ฐ’์ด ์ดํ•˜์ธ ๋ฐ•์Šค๋“ค์„ ์ œ๊ฑฐํ•˜์—ฌ ์ค‘๋ณต ํƒ์ง€๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

box_intersection

float box_intersection(box a, box b)
{
    float w = overlap(a.x, a.w, b.x, b.w);
    float h = overlap(a.y, a.h, b.y, b.h);
    if(w < 0 || h < 0) return 0;
    float area = w*h;
    return area;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: box_intersection

์ž…๋ ฅ:

  • box a, box b (bounding box ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ตฌ์กฐ์ฒด)

๋™์ž‘:

  • ๋‘ ๊ฐœ์˜ bounding box a์™€ b๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ด๋“ค์˜ ๊ต์ฐจ ๋ฉด์ ์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

์„ค๋ช…:

  • overlap ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‘ bounding box์˜ x, y ์ขŒํ‘œ์— ๋Œ€ํ•œ ๊ต์ฐจ ๋ถ€๋ถ„์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•œ ํ›„, ์ด๋“ค ๊ธธ์ด๋ฅผ ๊ณฑํ•˜์—ฌ ๊ต์ฐจ ๋ฉด์ ์„ ๊ณ„์‚ฐํ•œ๋‹ค.

  • ๋งŒ์•ฝ ๊ต์ฐจํ•˜๋Š” ๋ถ€๋ถ„์ด ์—†๋‹ค๋ฉด ๋ฉด์ ์€ 0์ด ๋œ๋‹ค.

box_union

float box_union(box a, box b)
{
    float i = box_intersection(a, b);
    float u = a.w*a.h + b.w*b.h - i;
    return u;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: box_union

์ž…๋ ฅ:

  • ๋‘ ๊ฐœ์˜ box(a, b)

๋™์ž‘:

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ๋‘ ๊ฐœ์˜ box์˜ union์„ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค. union์€ ๋‘ box๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋ฉด์ ์„ ํ•ฉ์นœ ๊ฐ’์ด๋‹ค.

์„ค๋ช…:

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ๋‘ ๊ฐœ์˜ box a, b์— ๋Œ€ํ•ด์„œ, ๊ฐ box์˜ ๋ฉด์ (w*h)์„ ๋”ํ•œ ํ›„์— box_intersection() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ต์ฐจํ•˜๋Š” ์˜์—ญ์˜ ๋ฉด์ (i)์„ ๊ตฌํ•œ๋‹ค.

  • ๊ทธ๋ฆฌ๊ณ  ๋‘ box์˜ ๋ฉด์ ์˜ ํ•ฉ์—์„œ ๊ต์ฐจํ•˜๋Š” ์˜์—ญ(i)์„ ๋บ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ์ด ๊ฐ’์ด ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ๋‘ box์˜ union ๊ฐ’์ด ๋œ๋‹ค.

box_iou

float box_iou(box a, box b)
{
    return box_intersection(a, b)/box_union(a, b);
}
  • IOU๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

box_rmse

float box_rmse(box a, box b)
{
    return sqrt(pow(a.x-b.x, 2) +
                pow(a.y-b.y, 2) +
                pow(a.w-b.w, 2) +
                pow(a.h-b.h, 2));
}

ํ•จ์ˆ˜ ์ด๋ฆ„: box_rmse

์ž…๋ ฅ:

  • box ๊ตฌ์กฐ์ฒด์ธ a์™€ b

๋™์ž‘:

  • ๋‘ ๊ฐœ์˜ box ๊ตฌ์กฐ์ฒด a์™€ b์˜ ์ขŒํ‘œ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ root mean square error(RMSE)์„ ๊ณ„์‚ฐํ•œ๋‹ค.

์„ค๋ช…:

  • box ๊ตฌ์กฐ์ฒด๋Š” ๋ฐ”์šด๋”ฉ ๋ฐ•์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ตฌ์กฐ์ฒด์ด๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ box ๊ตฌ์กฐ์ฒด a์™€ b๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ๊ฐ ์ขŒํ‘œ๊ฐ’(x, y, w, h)์„ ์ด์šฉํ•˜์—ฌ RMSE๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

  • RMSE๋Š” ์˜ˆ์ธก๊ฐ’๊ณผ ์‹ค์ œ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ, ์ฐจ์ด์˜ ์ œ๊ณฑ์„ ํ‰๊ท ๋‚ด๊ณ  ๋‹ค์‹œ ๋ฃจํŠธ๋ฅผ ์”Œ์šด ๊ฐ’์ด๋‹ค.

  • ๋”ฐ๋ผ์„œ ์ด ํ•จ์ˆ˜์—์„œ๋Š” ๊ฐ ์ขŒํ‘œ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ํ‰๊ท ์„ ๋‚ด๊ณ  ๋‹ค์‹œ ๋ฃจํŠธ๋ฅผ ์ทจํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

derivative

dbox derivative(box a, box b)
{
    dbox d;
    d.dx = 0;
    d.dw = 0;
    float l1 = a.x - a.w/2;
    float l2 = b.x - b.w/2;
    if (l1 > l2){
        d.dx -= 1;
        d.dw += .5;
    }
    float r1 = a.x + a.w/2;
    float r2 = b.x + b.w/2;
    if(r1 < r2){
        d.dx += 1;
        d.dw += .5;
    }
    if (l1 > r2) {
        d.dx = -1;
        d.dw = 0;
    }
    if (r1 < l2){
        d.dx = 1;
        d.dw = 0;
    }

    d.dy = 0;
    d.dh = 0;
    float t1 = a.y - a.h/2;
    float t2 = b.y - b.h/2;
    if (t1 > t2){
        d.dy -= 1;
        d.dh += .5;
    }
    float b1 = a.y + a.h/2;
    float b2 = b.y + b.h/2;
    if(b1 < b2){
        d.dy += 1;
        d.dh += .5;
    }
    if (t1 > b2) {
        d.dy = -1;
        d.dh = 0;
    }
    if (b1 < t2){
        d.dy = 1;
        d.dh = 0;
    }
    return d;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: dbox derivative(box a, box b)

์ž…๋ ฅ:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • ์ž…๋ ฅ๋œ ๋‘ ์ƒ์ž์˜ ๊ต์ฐจ ์˜์—ญ(intersection)์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ์ƒ์ž a์™€ b์˜ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ๋œ ๋‘ ์ƒ์ž์˜ ์œ„์น˜, ๋„ˆ๋น„, ๋†’์ด๋ฅผ ์ด์šฉํ•˜์—ฌ l1, l2, r1, r2, t1, t2, b1, b2 ๋ณ€์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • l1, l2๋Š” ์ƒ์ž a์™€ b์˜ ์™ผ์ชฝ ๋ ์ขŒํ‘œ, r1, r2๋Š” ์ƒ์ž a์™€ b์˜ ์˜ค๋ฅธ์ชฝ ๋ ์ขŒํ‘œ, t1, t2๋Š” ์ƒ์ž a์™€ b์˜ ์œ„์ชฝ ๋ ์ขŒํ‘œ, b1, b2๋Š” ์ƒ์ž a์™€ b์˜ ์•„๋ž˜์ชฝ ๋ ์ขŒํ‘œ์ž…๋‹ˆ๋‹ค.

  • ๊ณ„์‚ฐ๋œ ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ƒ์ž a์™€ b์˜ ๊ต์ฐจ ์˜์—ญ์ด ์™„์ „ํžˆ ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ๋ฏธ๋ถ„๊ฐ’์€ 0์ด ๋ฉ๋‹ˆ๋‹ค.

  • ํ•จ์ˆ˜๋Š” ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ dbox ๊ตฌ์กฐ์ฒด์— ์ €์žฅํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๋ฏธ๋ถ„๊ฐ’์€ dintersect ํ•จ์ˆ˜์—์„œ ๊ต์ฐจ ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ณ„์‚ฐ๋œ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

dintersect

dbox dintersect(box a, box b)
{
    float w = overlap(a.x, a.w, b.x, b.w);
    float h = overlap(a.y, a.h, b.y, b.h);
    dbox dover = derivative(a, b);
    dbox di;

    di.dw = dover.dw*h;
    di.dx = dover.dx*h;
    di.dh = dover.dh*w;
    di.dy = dover.dy*w;

    return di;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: dintersect

์ž…๋ ฅ:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • ์ž…๋ ฅ๋œ ๋‘ ์ƒ์ž์˜ ๊ต์ฐจ ์˜์—ญ(intersection)์„ ๊ณ„์‚ฐํ•˜๊ณ , ๊ต์ฐจ ์˜์—ญ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ์ž…๋ ฅ๋œ ๋‘ ์ƒ์ž์˜ ๊ต์ฐจ ์˜์—ญ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด overlap ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. overlap ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์„ ๋ถ„์ด ๊ฒน์น˜๋Š” ๊ธธ์ด(๋„ˆ๋น„ ๋˜๋Š” ๋†’์ด)๋ฅผ ๊ณ„์‚ฐํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. overlap ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ต์ฐจ ์˜์—ญ์˜ ๋„ˆ๋น„(w)์™€ ๋†’์ด(h)๋ฅผ ๊ตฌํ•˜๊ณ , ์ƒ์ž a์™€ b์˜ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•˜๋Š” derivative ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • derivative ํ•จ์ˆ˜๋Š” ์ƒ์ž a์™€ b์˜ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’(๋„ํ•จ์ˆ˜)์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋กœ, ์ž…๋ ฅ๋œ ๋‘ ์ƒ์ž์˜ ์œ„์น˜, ๋„ˆ๋น„, ๋†’์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์‚ฐ๋œ ๋ฏธ๋ถ„๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์ƒ์ž a์™€ b์˜ ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ , ์ด ๊ฐ’์„ dbox ๊ตฌ์กฐ์ฒด์— ์ €์žฅํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜ํ™˜๋˜๋Š” dbox ๊ตฌ์กฐ์ฒด์—๋Š” ๊ต์ฐจ ์˜์—ญ์— ๋Œ€ํ•œ ๋„ˆ๋น„์™€ ๋†’์ด์— ๋Œ€ํ•œ ๋ฏธ๋ถ„๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์—ญ์ „ํŒŒ(backpropagation)๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜, ์ตœ์ ํ™”(optimization) ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋ฏธ๋ถ„๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ๊ฒฝ์‚ฌํ•˜๊ฐ•๋ฒ•(gradient descent) ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

dunion

dbox dunion(box a, box b)
{
    dbox du;

    dbox di = dintersect(a, b);
    du.dw = a.h - di.dw;
    du.dh = a.w - di.dh;
    du.dx = -di.dx;
    du.dy = -di.dy;

    return du;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: dunion

์ž…๋ ฅ: ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b์˜ ์œ ๋‹ˆ์˜จ์„ ๊ณ„์‚ฐํ•˜์—ฌ, ๋‘ ๋ฐ•์Šค๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋ฐ•์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ์ž…๋ ฅ์œผ๋กœ ์ฃผ์–ด์ง„ ๋‘ ๋ฐ•์Šค a, b์— ๋Œ€ํ•ด์„œ, ๋‘ ๋ฐ•์Šค๊ฐ€ ๊ณตํ†ต์œผ๋กœ ๊ฐ€์ง€๋Š” ์˜์—ญ์˜ ๋„“์ด๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‘ ๋ฐ•์Šค๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋ฐ•์Šค์˜ ๋„“์ด๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

  • ์ดํ›„, du ๊ตฌ์กฐ์ฒด์— ์ด ์ž‘์€ ๋ฐ•์Šค์˜ ํญ๊ณผ ๋†’์ด์˜ ์ฐจ์ด, ๊ทธ๋ฆฌ๊ณ  ์ค‘์‹ฌ ์ขŒํ‘œ์˜ ์ฐจ์ด๋ฅผ ์ €์žฅํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋•Œ, dintersect ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‘ ๋ฐ•์Šค์˜ ์ธํ„ฐ์„น์…˜์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

test

void test_dunion()
{
    box a = {0, 0, 1, 1};
    box dxa= {0+.0001, 0, 1, 1};
    box dya= {0, 0+.0001, 1, 1};
    box dwa= {0, 0, 1+.0001, 1};
    box dha= {0, 0, 1, 1+.0001};

    box b = {.5, .5, .2, .2};
    dbox di = dunion(a,b);
    printf("Union: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
    float inter =  box_union(a, b);
    float xinter = box_union(dxa, b);
    float yinter = box_union(dya, b);
    float winter = box_union(dwa, b);
    float hinter = box_union(dha, b);
    xinter = (xinter - inter)/(.0001);
    yinter = (yinter - inter)/(.0001);
    winter = (winter - inter)/(.0001);
    hinter = (hinter - inter)/(.0001);
    printf("Union Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
}

void test_dintersect()
{
    box a = {0, 0, 1, 1};
    box dxa= {0+.0001, 0, 1, 1};
    box dya= {0, 0+.0001, 1, 1};
    box dwa= {0, 0, 1+.0001, 1};
    box dha= {0, 0, 1, 1+.0001};

    box b = {.5, .5, .2, .2};
    dbox di = dintersect(a,b);
    printf("Inter: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
    float inter =  box_intersection(a, b);
    float xinter = box_intersection(dxa, b);
    float yinter = box_intersection(dya, b);
    float winter = box_intersection(dwa, b);
    float hinter = box_intersection(dha, b);
    xinter = (xinter - inter)/(.0001);
    yinter = (yinter - inter)/(.0001);
    winter = (winter - inter)/(.0001);
    hinter = (hinter - inter)/(.0001);
    printf("Inter Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
}

void test_box()
{
    test_dintersect();
    test_dunion();
    box a = {0, 0, 1, 1};
    box dxa= {0+.00001, 0, 1, 1};
    box dya= {0, 0+.00001, 1, 1};
    box dwa= {0, 0, 1+.00001, 1};
    box dha= {0, 0, 1, 1+.00001};

    box b = {.5, 0, .2, .2};

    float iou = box_iou(a,b);
    iou = (1-iou)*(1-iou);
    printf("%f\n", iou);
    dbox d = diou(a, b);
    printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh);

    float xiou = box_iou(dxa, b);
    float yiou = box_iou(dya, b);
    float wiou = box_iou(dwa, b);
    float hiou = box_iou(dha, b);
    xiou = ((1-xiou)*(1-xiou) - iou)/(.00001);
    yiou = ((1-yiou)*(1-yiou) - iou)/(.00001);
    wiou = ((1-wiou)*(1-wiou) - iou)/(.00001);
    hiou = ((1-hiou)*(1-hiou) - iou)/(.00001);
    printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou);
}
Inter: 0.100000 0.100000 0.050000 0.050000
Inter Manual 0.100015 0.100015 0.050012 0.050012

Union: -0.100000 -0.100000 0.950000 0.950000
Union Manual -0.100136 -0.100136 0.950098 0.950098

IOU : 0.500000 0.000000 -0.800000 -0.800000
IOU manual : -0.390865 0.001386 -0.156757 0.039369

์‹คํ–‰ ๊ฒฐ๊ณผ ์ž…๋‹ˆ๋‹ค. ๋ญ”๊ฐ€ Inter, Union์€ ๋ฏธ๋ถ„ ๊ฐ’์ด ๋“ค์–ด ๋งž๋Š”๋ฐ IOU๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ test_iou์™€ diou๋Š” darknet์—์„œ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ diou์— ๋‚ญ๋น„ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‚˜๋ด…๋‹ˆ๋‹ค.

  • || 1์ด ๋ถ€๋ถ„์„ ์ง€์šฐ๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

IOU: 0.392006 0.000000 0.158310 -0.037693
IOU manual -0.390865 0.001386 -0.156757 0.039369
  1. ํ•จ์ˆ˜ ์ด๋ฆ„: test_dunion()

  • ์ž…๋ ฅ: ์—†์Œ

  • ๋™์ž‘: dunion() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๋ฐ•์Šค์˜ ํ•ฉ์ง‘ํ•ฉ์„ ๊ณ„์‚ฐํ•˜๊ณ , ์ˆ˜๋™์œผ๋กœ ๊ณ„์‚ฐํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  • ์„ค๋ช…: ๋‘ ๊ฐœ์˜ ๋ฐ•์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , dunion() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ฉ์ง‘ํ•ฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„, ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  1. ํ•จ์ˆ˜ ์ด๋ฆ„: test_dintersect()

  • ์ž…๋ ฅ: ์—†์Œ

  • ๋™์ž‘: dintersect() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๋ฐ•์Šค์˜ ๊ต์ง‘ํ•ฉ์„ ๊ณ„์‚ฐํ•˜๊ณ , ์ˆ˜๋™์œผ๋กœ ๊ณ„์‚ฐํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  • ์„ค๋ช…: ๋‘ ๊ฐœ์˜ ๋ฐ•์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , dintersect() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ต์ง‘ํ•ฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„, ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  1. ํ•จ์ˆ˜ ์ด๋ฆ„: test_box()

  • ์ž…๋ ฅ: ์—†์Œ

  • ๋™์ž‘: box_iou() ํ•จ์ˆ˜์™€ diou() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๋ฐ•์Šค์˜ IoU(Intersection over Union) ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ , ์ˆ˜๋™์œผ๋กœ ๊ณ„์‚ฐํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  • ์„ค๋ช…: ๋‘ ๊ฐœ์˜ ๋ฐ•์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , box_iou() ํ•จ์ˆ˜์™€ diou() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ IoU ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„, ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์•ž์„œ ์ •์˜ํ•œ test_dunion() ํ•จ์ˆ˜์™€ test_dintersect() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์˜ ์ •ํ™•์„ฑ๋„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

diou

dbox diou(box a, box b)
{
    float u = box_union(a,b);
    float i = box_intersection(a,b);
    dbox di = dintersect(a,b);
    dbox du = dunion(a,b);
    dbox dd = {0,0,0,0};

    if(i <= 0 || 1) {         // ์ด์ƒํ•œ ๋‚ญ๋น„ ์ฝ”๋“œ
        dd.dx = b.x - a.x;
        dd.dy = b.y - a.y;
        dd.dw = b.w - a.w;
        dd.dh = b.h - a.h;
        return dd;
    }

    dd.dx = 2*pow((1-(i/u)),1)*(di.dx*u - du.dx*i)/(u*u);
    dd.dy = 2*pow((1-(i/u)),1)*(di.dy*u - du.dy*i)/(u*u);
    dd.dw = 2*pow((1-(i/u)),1)*(di.dw*u - du.dw*i)/(u*u);
    dd.dh = 2*pow((1-(i/u)),1)*(di.dh*u - du.dh*i)/(u*u);
    return dd;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: dbox_diou

์ž…๋ ฅ:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • ๋‘ ์ƒ์ž์˜ ๊ต์ฐจ ๋ถ€ํ”ผ(dbox_intersection)์™€ ํ•ฉ์ง‘ํ•ฉ ๋ถ€ํ”ผ(dbox_union)๋ฅผ ๊ณ„์‚ฐํ•œ ํ›„, ๊ต์ฐจํ•œ ์˜์—ญ์˜ ๋ฏธ๋ถ„(dbox)์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

  • ๊ต์ฐจ ๋ถ€ํ”ผ๊ฐ€ 0 ์ดํ•˜๊ฑฐ๋‚˜ 1 ์ด์ƒ์ธ ๊ฒฝ์šฐ, ๋‘ ์ƒ์ž์˜ ์œ„์น˜ ์ฐจ์ด๋ฅผ ๋ฏธ๋ถ„ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ๋‘ ์ƒ์ž์˜ ๊ต์ฐจํ•œ ์˜์—ญ์˜ ๋น„์œจ์— ๋”ฐ๋ผ ๋ฏธ๋ถ„ ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ์ด ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์ƒ์ž์˜ ์œ„์น˜์™€ ํฌ๊ธฐ ์ฐจ์ด์— ๋Œ€ํ•œ ๋ฏธ๋ถ„ ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒ์ž์˜ ์œ„์น˜์™€ ํฌ๊ธฐ ์ฐจ์ด๊ฐ€ ์ž‘์€ ๊ฒฝ์šฐ, ์ด ๋ฏธ๋ถ„ ๊ฐ’์€ ์ƒ์ž๋ฅผ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•  ๋•Œ ํ•„์š”ํ•œ ์ •๋ณด๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด ํ•จ์ˆ˜๋Š” YOLOv3์™€ ๊ฐ™์€ ๋”ฅ๋Ÿฌ๋‹ ๋ชจ๋ธ์—์„œ ๋ฌผ์ฒด ๊ฒ€์ถœ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

do_nms

void do_nms(box *boxes, float **probs, int total, int classes, float thresh)
{
    int i, j, k;
    for(i = 0; i < total; ++i){
        int any = 0;
        for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0);
        if(!any) {
            continue;
        }
        for(j = i+1; j < total; ++j){
            if (box_iou(boxes[i], boxes[j]) > thresh){
                for(k = 0; k < classes; ++k){
                    if (probs[i][k] < probs[j][k]) probs[i][k] = 0;
                    else probs[j][k] = 0;
                }
            }
        }
    }
}

ํ•จ์ˆ˜ ์ด๋ฆ„: do_nms

์ž…๋ ฅ:

  • boxes: ๋ฐ•์Šค ์ขŒํ‘œ ์ •๋ณด๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด

  • probs: ๋ฐ•์Šค์— ๋Œ€ํ•œ ๊ฐ ํด๋ž˜์Šค์˜ ํ™•๋ฅ  ์ •๋ณด๋ฅผ ๋‹ด์€ 2์ฐจ์› ๋ฐฐ์—ด

  • total: ์ „์ฒด ๋ฐ•์Šค์˜ ๊ฐœ์ˆ˜

  • classes: ๋ถ„๋ฅ˜ํ•  ํด๋ž˜์Šค์˜ ๊ฐœ์ˆ˜

  • thresh: IoU ์ž„๊ณ„๊ฐ’

๋™์ž‘:

  • ๋ฐ•์Šค๋“ค์„ ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌํ•˜๋ฉด์„œ ํ•ด๋‹น ๋ฐ•์Šค๊ฐ€ ์–ด๋–ค ํด๋ž˜์Šค์—๋„ ์†ํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ ๋ฐ•์Šค๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค.

  • ์†ํ•œ ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜๋Š” ๋ฐ•์Šค๋“ค ์ค‘ IoU ๊ฐ’์ด ์ž„๊ณ„๊ฐ’(thresh)๋ณด๋‹ค ํฌ๋‹ค๋ฉด, ํ™•๋ฅ ๊ฐ’์ด ์ž‘์€ ๋ฐ•์Šค๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ™•๋ฅ ๊ฐ’์„ 0์œผ๋กœ ๋งŒ๋“ ๋‹ค.

์„ค๋ช…:

  • Non-maximum suppression(NMS) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•œ ํ•จ์ˆ˜๋กœ, ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ค‘๋ณต๋œ ๋ฐ•์Šค๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ๋ฐ•์Šค์™€ ํด๋ž˜์Šค๋ณ„ ํ™•๋ฅ  ์ •๋ณด๋ฅผ ์ด์šฉํ•ด IoU ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ , IoU ๊ฐ’์ด ์ž„๊ณ„๊ฐ’์„ ๋„˜๋Š” ๋ฐ•์Šค ์ค‘ ํ™•๋ฅ ๊ฐ’์ด ์ž‘์€ ๋ฐ•์Šค๋Š” ์ œ๊ฑฐํ•œ๋‹ค.

  • ์ด ๊ณผ์ •์„ ๊ฑฐ์ณ ์ตœ์ข…์ ์œผ๋กœ ๋‚จ์€ ๋ฐ•์Šค๋“ค์€ ์ค‘๋ณต์ด ์ œ๊ฑฐ๋œ ํ›„๋ณด ๊ฐ์ฒด๋“ค์ด ๋œ๋‹ค.

encode_box

box encode_box(box b, box anchor)
{
    box encode;
    encode.x = (b.x - anchor.x) / anchor.w;
    encode.y = (b.y - anchor.y) / anchor.h;
    encode.w = log2(b.w / anchor.w);
    encode.h = log2(b.h / anchor.h);
    return encode;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: encode_box

์ž…๋ ฅ:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ box b์™€ anchor๋ฅผ ์ด์šฉํ•˜์—ฌ bounding box ์ •๋ณด๋ฅผ ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • encode_box ํ•จ์ˆ˜๋Š” bounding box regression์„ ์œ„ํ•ด ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ bounding box ์ •๋ณด์™€ anchor ์ •๋ณด๋ฅผ ์ด์šฉํ•˜์—ฌ bounding box ์ •๋ณด๋ฅผ ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ b์˜ (x, y, w, h) ๊ฐ’๊ณผ anchor์˜ (x, y, w, h) ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด bounding box ์ •๋ณด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด bounding box ์ •๋ณด encode์˜ (x, y, w, h) ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

    • encode.x = (b.x - anchor.x) / anchor.w

    • encode.y = (b.y - anchor.y) / anchor.h

    • encode.w = log2(b.w / anchor.w)

    • encode.h = log2(b.h / anchor.h)

  • ์ด๋ ‡๊ฒŒ ์ธ์ฝ”๋”ฉ๋œ bounding box ์ •๋ณด๋Š” ๋ชจ๋ธ ํ•™์Šต ์‹œ bounding box regression์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

decode_box

box decode_box(box b, box anchor)
{
    box decode;
    decode.x = b.x * anchor.w + anchor.x;
    decode.y = b.y * anchor.h + anchor.y;
    decode.w = pow(2., b.w) * anchor.w;
    decode.h = pow(2., b.h) * anchor.h;
    return decode;
}

ํ•จ์ˆ˜ ์ด๋ฆ„: decode_box

์ž…๋ ฅ:

  • ๋ฐ•์Šค a์™€ ๋ฐ•์Šค b

๋™์ž‘:

  • anchor๋ฅผ ๊ธฐ์ค€์œผ๋กœ b์—์„œ ๋””์ฝ”๋”ฉ๋œ box๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. x, y, w, h ๊ฐ’์„ ์ƒˆ๋กœ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • ๋””์ฝ”๋”ฉ์€ ์ธ์ฝ”๋”ฉ๋œ ์ƒ์ž์™€ ์•ต์ปค ์ƒ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์˜ˆ์ธก๋œ ์ƒ์ž์˜ ์ขŒํ‘œ์™€ ํฌ๊ธฐ๋ฅผ ๋ณต์›ํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค.

  • ์ด ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ์ธ์ฝ”๋”ฉ๋œ box b์™€ ์•ต์ปค ์ƒ์ž anchor๋ฅผ ์ด์šฉํ•˜์—ฌ ์˜ˆ์ธก๋œ ์ƒ์ž์˜ ์‹ค์ œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜์—ฌ box ๊ตฌ์กฐ์ฒด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • x, y, w, h ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฝ”๋”ฉ๋œ ๊ฐ’ b์™€ anchor ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ๋””์ฝ”๋”ฉ๋œ ์ƒ์ž์˜ ์ขŒํ‘œ์™€ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

Last updated

Was this helpful?