nms.cpp
#include <iostream> #include <vector> #include <algorithm> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; double IOU(const Rect& r1, const Rect& r2) { int x1 = std::max(r1.x, r2.x); int y1 = std::max(r1.y, r2.y); int x2 = std::min(r1.x+r1.width, r2.x+r2.width); int y2 = std::min(r1.y+r1.height, r2.y+r2.height); int w = std::max(0, (x2-x1+1)); int h = std::max(0, (y2-y1+1)); double inter = w * h; double o = inter / (r1.area() + r2.area() - inter); return (o >= 0) ? o : 0; } void nms(vector<Rect>& proposals, const double nms_threshold) { vector<int> scores; for(auto i : proposals) scores.push_back(i.area()); vector<int> index; for(int i = 0; i < scores.size(); ++i){ index.push_back(i); } sort(index.begin(), index.end(), [&](int a, int b){ return scores[a] > scores[b]; }); vector<bool> del(scores.size(), false); for(size_t i = 0; i < index.size(); i++){ if( !del[index[i]]){ for(size_t j = i+1; j < index.size(); j++){ if(IOU(proposals[index[i]], proposals[index[j]]) > nms_threshold){ del[index[j]] = true; } } } } vector<Rect> new_proposals; for(const auto i : index){ if(!del[i]) new_proposals.push_back(proposals[i]); } proposals = new_proposals; } void test_nms() { Mat img = imread("D:\\test\\test.jpg"); Mat img2 = img.clone(); // prepare data vector<Rect> proposals; Point2i origin(20, 20); int w = 100; int h = 200; for (auto i : {0,1,2,3,4,5}) proposals.push_back(Rect(origin.x + 10*i, origin.y + 20*i, w - 5*i, h-7*i)); origin.x = 200; origin.y = 400; w = 300; h = 120; for (auto i : {0,1,2,3,4,5}) proposals.push_back(Rect(origin.x + 10*i, origin.y + 20*i, w - 5*i, h-7*i)); proposals.push_back(Rect(400, 200, 386, 239)); proposals.push_back(Rect(200, 120, 186, 209)); proposals.push_back(Rect(310, 376, 286, 139)); for(auto rect : proposals) rectangle(img, rect, Scalar(0, 255, 255), 2); imshow("before", img); // nms nms(proposals, 0.1); for(auto rect : proposals) rectangle(img2, rect, Scalar(0, 255, 255), 2); imshow("after", img2); waitKey(0); } int main() { test_nms(); return 0; }test.pro
TEMPLATE = app TARGET = test CONFIG += console c++11 CONFIG -= qt CONFIG -= app_bundle INCLUDEPATH += . # Input SOURCES += nms.cpp win32{ LIBS_PATH = E:\debug\caffe_environment_x86_x64 ARCH = x86 #x64 # opencv PATH_OPENCV_INCLUDE = $${LIBS_PATH}\OpenCV\opencv310\build\include PATH_OPENCV_LIBRARIES = $${LIBS_PATH}\OpenCV\opencv310\build\\$${ARCH}\vc12\lib VERSION_OPENCV = 310 INCLUDEPATH += $${PATH_OPENCV_INCLUDE} CONFIG(debug, debug|release){ LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_core$${VERSION_OPENCV}d LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_highgui$${VERSION_OPENCV}d LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_imgcodecs$${VERSION_OPENCV}d LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_imgproc$${VERSION_OPENCV}d LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_video$${VERSION_OPENCV}d LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_videoio$${VERSION_OPENCV}d } CONFIG(release, debug|release){ LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_core$${VERSION_OPENCV} LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_highgui$${VERSION_OPENCV} LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_imgcodecs$${VERSION_OPENCV} LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_imgproc$${VERSION_OPENCV} LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_video$${VERSION_OPENCV} LIBS += -L$${PATH_OPENCV_LIBRARIES} -lopencv_videoio$${VERSION_OPENCV} } }https://github.com/yang-song/NMS/blob/master/nms.cpp