nms-python和C

代码

import  numpy as np

def nms(bboxes, iou_threshold):
    x1 = bboxes[:, 0]
    y1 = bboxes[:, 1]
    x2 = bboxes[:, 2]
    y2 = bboxes[:, 3]
    score = bboxes[:, 4]
    area = (x2 - x1 + 1) * (y2 - y1 + 1)
    index = area.argsort()[::-1]
    res = []
    while index.size > 0:
        i = index[0]
        res.append(i)
        xx1 = np.maximum(x1[i], x1[index[1:] ])
        yy1 = np.maximum(y1[i], y1[index[1:] ])
        xx2 = np.minimum(x2[i], x2[index[1:] ])
        yy2 = np.minimum(y2[i], y2[index[1:] ])
        width = np.maximum(0, (xx2 - xx1 + 1))
        height = np.maximum(0, (yy2 - yy1 + 1))
        o_area = width * height
        print("o_area ", o_area)
        iou = o_area / (area[i] + area[index[1:]] - o_area)
        print("iou ", iou)
        ne_inde = np.where(iou <= iou_threshold)[0]
        index = index[ne_inde +1]
    return res

off = 10
print(off)
#
bboxes = np.array([[10, 10, 10 + off, 10 + off, 0.91], [12, 12, 12 + off, 12 + off, 0.9] , [14, 14, 14+off, 14+ off, 0.7], [15, 15, 15+off, 15+ off, 0.8]])
res = nms(bboxes, 0.3)
print(res)



/*
 ============================================================================
 Name        : NMS.c
 Author      : yiqun
 Version     :
 Copyright   : Your copyright notice
 Description : NMS in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <iostream>

#define MAX(a,b)(a>b?a:b)
#define MIN(a,b)(a<=b?a:b)
#define BOX_SIZE 4
#define THRESH 0.3f

//候选框
typedef struct {
    float lx, ly, rx, ry;	//左上角x  左上角y	 右下角x	 右下角y
    float cfd;	//置信度 Confidence
    int supression; //是否被抑制
} box;

//float overlap(float a_l, float a_r, float b_l, float b_r);
//
传入两个候选框变量某一维度坐标值,返回重叠部分的宽和高
//float overlap(float a_l, float a_r, float b_l, float b_r) {	//返回值是否可以优化??//传入指针是否更快??
//    //printf("a左边: %f,a右边: %f,b左边: %f,b右边: %f", a_l, a_r, b_r, b_r);
//    float sum_sides = a_r - a_l + b_r - b_l;	//同一方向两个边长之和	//是否要绝对值
//    float new_sides = MAX(a_r, b_r) - MIN(a_l, b_l);	//同一方向长度并集 //用max还是绝对值??优化。
//    return  sum_sides - new_sides;
//}

传入两个候选框变量a、b,返回相交面积值
//float box_intersection(box *a, box *b)	//传入指针是否更快??
//{
//    float w = overlap(a->lx, a->rx, b->lx, b->rx);
//    float h = overlap(a->ly, a->ry, b->ly, b->ry);
//    //printf("w: %f, h: %f", w, h);
//    if (w <= 0 || h <= 0) return 0;
//    float area = w * h;	//直接返回 不创建变量??
//    return w * h;
//}

传入两个候选框变量a、b,返回并集面积值
//float box_union(box *a, box *b) {	//传入指针是否更快??
//    float insersection = box_intersection(a, b);	//减少函数调用还是开辟变量空间进行优化??
//    float areaA = (a->rx - a->lx) * (a->ly - a->ry);	//是否使用绝对值??
//    float areaB = (b->rx - b->lx) * (b->ly - b->ry);
//    float area = areaA + areaB - insersection;	//直接返回 不创建变量??
//    return area;
//}


float box_area(box *a){
    float w = MAX((a->rx - a->lx + 1), 0);
    float h = MAX((a->ry - a->ly + 1), 0);
    return w * h;
}

float box_com(box *a, box *b){
    float x1 = MAX(a->lx, b->lx);
    float y1 = MAX(a->ly, b->ly);
    float x2 = MIN(a->rx, b->rx);
    float y2 = MIN(a->ry, b->ry);
    float w = MAX(0, (x2 - x1 + 1));
    float h = MAX(0, (y2 - y1 + 1));
    float o_area = w * h;
    return o_area;
}


float box_iou2(box *a, box *b){
    float o_area = box_com(a, b);
    float a_a = box_area(a);
    float b_a = box_area(b);
    float iou = o_area / (a_a + b_a  - o_area);
    return iou;
}
//传入两个候选框变量a、b,返回交并比值
//float box_iou(box *a, box *b) //传入指针是否更快??
//{
//    std::cout << box_intersection(a, b) << std::endl;
       iou = o_area / (area[i] + area[index[1:]] - o_area)
//    return box_intersection(a, b)/box_union(a, b);	//dsp可进行除法优化!!
//}

//归并排序
void merge(box* B, box* temp, int l, int mid, int r) {
    int i = l, j = mid + 1, m = 1, k = 1;
    while (i <= mid && j <= r) {
        if ((B + i)->cfd < (B + j)->cfd)
            *(temp + m++) = *(B + j++);
        else
            *(temp + m++) = *(B + i++);
    }
    while (i <= mid)
        *(temp + m++) = *(B + i++);
    while (j <= r)
        *(temp + m++) = *(B + j++);
    for (k = 1; k <= r - l + 1; k++)
        *(B + l + k - 1) = *(temp + k);
}

//按照置信度从大到小排序
void sort_nms(box* B, box* temp, int l, int r) {		//(数组查找和链表删除哪个费时)C++ ERASE()源码改写
    if (l < r) {
        int mid = (l + r) / 2;
        sort_nms(B, temp, l, mid);
        sort_nms(B, temp, mid + 1, r);
        merge(B, temp, l, mid, r);
    }
}

//NMS算法,传入出入候选框集合、输入候选框对应置信度集合、阈值,返回输出候选框个数
int do_nms(box* B, box*D, float Nt) {
    int i;
    for (i = 0; i < BOX_SIZE; i++)
        printf("d: %.2f\n", (B + i)->cfd);

    box* temp = (box*)malloc(sizeof(box) * (BOX_SIZE+1));
    sort_nms(B, temp, 0, (BOX_SIZE - 1));
    free(temp);

    for (i = 0; i < BOX_SIZE; i++)
        printf("d: %.2f\n", (B + i)->cfd);

    int max_index = 0, current_index = 0;
    int j;
    float iou;
    while (current_index< BOX_SIZE) {	//探究一轮循环的方法,与所以输出框比较,递归??
        printf("current_index: %d\n", current_index);
        if (!((B+current_index)->supression)) {
            *(D + max_index) = *(B + current_index);
            (B + current_index)->supression = 1;
            for (j = current_index+1; j < BOX_SIZE; j++) {
                iou = box_iou2(D + max_index, B + j);
                printf("iou: %f\n", iou);
                if (iou >= Nt)
                    (B + j)->supression = 1;
            }
            max_index++;
        }
        current_index++;
    }
    return max_index;
}

//数据集分配处理
void data_clean(box* b) {
    b[0].lx = 10.0;
    b[0].ly = 10.0;
    b[0].rx = 20.0;
    b[0].ry = 20.0;
    b[0].cfd = 0.91f;
    b[0].supression = 0;

    b[1].lx = 12.0;
    b[1].ly = 12.0;
    b[1].rx = 22.0;
    b[1].ry = 22.0;
    b[1].cfd = 0.90f;
    b[1].supression = 0;

    b[2].lx = 14.0;
    b[2].ly = 14.0;
    b[2].rx = 24.0;
    b[2].ry = 24.0;
    b[2].cfd = 0.70f;
    b[2].supression = 0;

    b[3].lx = 15.0;
    b[3].ly = 15.0;
    b[3].rx = 25.0;
    b[3].ry = 25.0;
    b[3].cfd = 0.80f;
    b[3].supression = 0;
}





int main(void) {
    box* b = (box*)malloc(sizeof(box) * BOX_SIZE);
//	float* s = (float*)malloc(sizeof(float) * BOX_SIZE);
    box* d = (box*)malloc(sizeof(box) * BOX_SIZE);
    data_clean(b);
    //计时器
    long i = 10000000L;
    clock_t start, finish;
    double duration;
    int count = 0;
    start = clock();
    /*******************/
    //while (i--) {
    count = do_nms(b, d, THRESH);
    printf("count: %d\n", count);
    //iou = box_iou(b+0,b+1);
    //}
    /*******************/
    finish = clock();
    duration = (finish - start) / CLOCKS_PER_SEC;
    printf("%f seconds\n", duration);
    //printf("IoU: %f\n", iou);
    //printf("s1: %f, s2: %f",*(s+0), *(s+1));
    if (d) {
        for (i = 0; i < count; i++)
            printf("d: %.2f\n", (d + i)->cfd);
    }
    free(b);
    free(d);
    system("pause");
    return EXIT_SUCCESS;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值