• NMS代码(python,C++)


    IOU计算

    python代码

    import numpy as np
    
    area1 = np.array(([1,1],[1,3],[3,3],[3,1]))
    area2 = np.array(([2,0],[4,0],[4,2],[2,2]))
    
    xy1_min = np.min(area1,axis=0)
    xy1_max = np.max(area1,axis=0)
    xy2_min = np.min(area2,axis=0)
    xy2_max = np.max(area2,axis=0)
    
    
    Ux_min = max(xy1_min[0],xy2_min[0])
    Ux_max = min(xy1_max[0],xy2_max[0])
    Uy_min = max(xy1_min[1],xy2_min[1])
    Uy_max = min(xy1_max[1],xy2_max[1])
    
    #交集面积
    area1 = (Ux_max - Ux_min) * Uy_max - Uy_min
    
    #并集面积
    area2 = (xy1_max[0] - xy1_min[0]) * (xy1_max[1] - xy1_min[1])
    area3 = (xy2_max[0] - xy2_min[0]) * (xy2_max[1] - xy2_min[1]) 
    res = area1 / (area2 + area3 - area1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    C++代码

    #include
    #include
    #include 
    #include
    using namespace std;
    
    vector<int> get_mins(vector<vector<int>>& Arr)
    {
    	vector<int> res(Arr[0].size(), INT_MAX);
    	for (int i = 0; i < Arr.size(); i++)
    	{
    		for (int j = 0; j < Arr[i].size(); j++)
    		{
    			if (res[j] > Arr[i][j])
    				res[j] = Arr[i][j];
    		}
    	}
    	return res;
    }
    
    vector<int> get_maxs(vector<vector<int>>& Arr)
    {
    	vector<int> res(Arr[0].size(), INT_MIN);
    	for (int i = 0; i < Arr.size(); i++)
    	{
    		for (int j = 0; j < Arr[i].size(); j++)
    		{
    			if (res[j] < Arr[i][j])
    				res[j] = Arr[i][j];
    		}
    	}
    	return res;
    }
    
    
    int main()
    {
    	vector<vector<int>> Arr1 = { {1,1},{3,3},{1,3},{3,1} };
    	vector<vector<int>> Arr2 = { {2,0},{4,0},{2,2},{4,2} };
    
    	vector<int> xy1_min = get_mins(Arr1);
    	vector<int> xy1_max = get_maxs(Arr1);
    	vector<int> xy2_min = get_mins(Arr2);
    	vector<int> xy2_max = get_maxs(Arr2);
    	//求交集
    	int x_min = max(xy1_min[0], xy2_min[0]);
    	int x_max = min(xy1_max[0], xy2_max[0]);
    	int y_min = max(xy1_min[1], xy2_min[1]);
    	int y_max = min(xy1_max[1], xy2_max[1]);
    	int area1 = (x_max - x_min) * (y_max - y_min);
    
    	cout << area1 << endl;
    	//求并集
    	int area2 = (xy1_max[0] - xy1_min[0]) * (xy1_max[1] - xy1_min[1]);
    	int area3 = (xy2_max[0] - xy2_min[0]) * (xy2_max[1] - xy2_min[1]);
    
    	float  res = float(area1) / (area3 + area2 - area1);
    	cout << res << endl;
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    NMS计算代码

    #include
    #include
    #include 
    
    using namespace std;
    
    float compute_iou(vector<float>& Arr1, vector<float>& Arr2)
    {
    	float h = min(Arr1[1], Arr2[1]) - max(Arr1[0], Arr2[0]);
    	float w = min(Arr1[3], Arr2[3]) - max(Arr1[2], Arr2[2]);
    	float area1 = h * w;
    
    	float area2 = (Arr1[1] - Arr1[0]) * (Arr1[3] - Arr1[2]);
    	float area3 = (Arr2[1] - Arr2[0]) * (Arr2[3] - Arr2[2]);
    	return area1 / (area2 + area2 - area2);
    }
    
    vector<vector<float>> compute_nms(vector<vector<float>>& infos, float iou_theta, float theta_score)
    {
    	vector<vector<float>> filter_infos;
    	//过滤分数达标的box
    	for (auto info : infos)
    	{
    		if (info[4] >= theta_score)
    			filter_infos.push_back(info);
    	}
    
    	vector<vector<float>> res;
    	vector<bool> set_idx(filter_infos.size(),true);//为使用的info索引
    
    	while (true)
    	{
    		//取score最大的box
    		int temp_idx = 0;
    		bool flag = false;//记录是否有为处理的box
    		
    		for (int i = 1; i < filter_infos.size() && set_idx[i]; i++)
    		{
    			if (filter_infos[i][4] > filter_infos[temp_idx][4])
    			{
    				flag = true;
    				temp_idx = i;
    			}
    		}
    
    		if (!flag)	break;
    		set_idx[temp_idx] = false;
    		vector<float> temp = filter_infos[temp_idx];
    		res.push_back(temp);
    		//计算选出的score最大的box于其他未使用的box的iou
    		vector<int> iou_idx;
    		for (int i = 0; i < filter_infos.size() & set_idx[i]; i++)
    		{
    			if (compute_iou(temp, filter_infos[i]) >= iou_theta)
    			{
    				res.push_back(filter_infos[i]);
    				set_idx[i] = false;
    			}
    		}
    	}
    	return res;	
    }
    
    int main()
    {
    	vector<vector<float>> infos = { {30, 10, 200, 200, 0.95},
    									{25, 15, 180, 220, 0.98},
    									{35, 40, 190, 170, 0.96},
    									{60, 60, 90, 90, 0.3},
    									{20, 30, 40, 50, 0.1} };
    
    	vector<vector<float>> res = compute_nms(infos, 0.5, 0.5);
    	for (int i = 0; i < res.size(); i++)
    	{
    		for (int j = 0; j < res[0].size(); j++)
    		{
    			cout << res[i][j] << " ";
    		}
    		cout << endl;
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    opencv(c++)显示NMS结果

    在这里插入图片描述

    在这里插入图片描述

    • code
    #include
    #include
    #include 
    #include
    #include "stdc++.h"
    using namespace cv;
    using namespace std;
    
    float compute_iou(vector<float>& Arr1, vector<float>& Arr2)
    {
    	//[x,y,w,h,score]
    	//[x-w/2.y+h/2] [x+w/2]
    	//求交集
    	float x_min = max(Arr1[0] - Arr1[2] / 2, Arr2[0] - Arr2[2]/2);
    	float x_max = min(Arr1[0] + Arr1[2] / 2, Arr2[0] + Arr2[2] / 2);
    	float y_min = max(Arr1[1] - Arr1[3] / 2, Arr2[1] - Arr2[3] / 2);
    	float y_max = min(Arr1[1] + Arr1[3] / 2, Arr2[1] + Arr2[3] / 2);
    	float area1 = (x_max - x_min) * (y_max - y_min);
    
    	//求并集
    	float area2 = Arr1[2] * Arr1[3];
    	float area3 = Arr2[2] * Arr2[3];
    	float res = area1 / (area2 + area3 - area1);
    	return res;
    }
    
    vector<vector<float>> compute_nms(vector<vector<float>>& infos, float iou_theta, float theta_score)
    {
    	vector<vector<float>> filter_infos;
    	//过滤分数达标的box
    	for (auto info : infos)
    	{
    		if (info[4] >= theta_score)
    			filter_infos.push_back(info);
    	}
    
    	vector<vector<float>> res;
    	vector<bool> set_idx(filter_infos.size(),true);//为使用的info索引
    
    	while (true)
    	{
    		//取score最大的box
    		int temp_idx = 0;
    		bool flag = false;//记录是否有为处理的box
    		int i = 1;
    		for (;i < filter_infos.size(); i++)
    		{
    			if (set_idx[i] && filter_infos[i][4] > filter_infos[temp_idx][4])
    			{
    				flag = true;
    				temp_idx = i;
    			}
    		}
    		if (!flag)	break;
    		set_idx[temp_idx] = false;
    		vector<float> temp = filter_infos[temp_idx];
    		res.push_back(temp);
    		//计算选出的score最大的box于其他未使用的box的iou
    		vector<int> iou_idx;
    		for (int j = 0; j < filter_infos.size(); j++)
    		{
    			if (set_idx[j])
    			{
    				if (compute_iou(temp, filter_infos[j]) >= iou_theta)
    				{
    					//res.push_back(filter_infos[i]);
    					set_idx[j] = false;
    				}
    			}
    
    		}
    	}
    
    	return res;	
    }
    
    void show_res(cv::Mat src, vector<vector<float>> infos,vector<vector<float>> colors)
    {
    	src.depth();
    	for (int i = 0; i < infos.size(); i++)
    	{
    		cv::Point P0 = cv::Point(int(infos[i][0] - infos[i][2] / 2), int(infos[i][1] + infos[i][3] / 2));
    		cv::Point P1 = cv::Point(int(infos[i][0] + infos[i][2] / 2), int(infos[i][1] - infos[i][3] / 2));
    		cv::Scalar color = cv::Scalar(colors[i][0], colors[i][1], colors[i][2]);
    		rectangle(src, P0, P1, color, 2, 8, 0);
    	}
    	cv::imshow("Lena", src);
    	cv::waitKey(0);
    	cv::destroyAllWindows();
    	return;
    }
    
    int main()
    {
    	string IMG_PATH = "C:/Users/hjfen/Pictures/Saved Pictures/";
    	vector<vector<float>> infos = { {330, 310, 300, 200, 0.95},
    									{325, 315, 180, 220, 0.98},
    									{335, 340, 190, 170, 0.96},
    									{360, 360, 90, 90, 0.3},
    									{320, 330, 40, 50, 0.1} };
    
    
    	vector<vector<float>> new_infos = compute_nms(infos, 0.5, 0.5);
    
    	vector<vector<float>> colors = { {125,125,0},
    										{255,0,0},
    										{0,255,0},
    										{0,125,125},
    										{100,100,100} };
    
    	cout << "Built with OpenCV " << CV_VERSION << endl;
    	cv::Mat src = imread(IMG_PATH + "2.jpg");
    	cv::Mat src1 = imread(IMG_PATH + "2.jpg");
    	show_res(src, infos, colors);
    
    	show_res(src1, new_infos, colors);
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
  • 相关阅读:
    Docker磁盘空间不足如何解决
    递归算法深入解析
    2 springMVC-处理器方法的返回值ModeVeiw,String,void,Object,List<Object>,String对象
    智能化水库监控,水库雨情在线监控系统解决方案
    信号与槽的连接方式
    服务器感染了.Malloxx勒索病毒,如何确保数据文件完整恢复?
    HazelEngine 学习记录 - Single Shader 2D Renderer
    云计算 - 阿里云最佳云上实践介绍 卓越架构
    设计模式——(装饰者模式)(组合模式)
    HTTPS的工作流程
  • 原文地址:https://blog.csdn.net/qhu1600417010/article/details/126274847