#include <vector>

// You must check the num_classes, conf_ths, nms_ths

struct Detection {
    cv::Rect2f box;
    float score;
    int class_idx;
};

std::vector<Detection> nms(const std::vector<Detection>& detections, float nms_ths) {
    std::vector<int> indices(detections.size());
    iota(indices.begin(), indices.end(), 0);

    std::sort(indices.begin(), indices.end(), [&](int i1, int i2) {
        return detections[i1].score > detections[i2].score;
        });

    std::vector<Detection> picked;

    while (!indices.empty()) {
        int current_index = indices.front();
        const auto& current_det = detections[current_index];
        picked.push_back(current_det);
        indices.erase(indices.begin());

        auto it = indices.begin();
        while (it != indices.end()) {
            const auto& det = detections[*it];
            float intersectionArea = (current_det.box & det.box).area();
            float unionArea = current_det.box.area() + det.box.area() - intersectionArea;
            float iou = intersectionArea / unionArea;

            if (iou > nms_ths) {
                it = indices.erase(it); // Remove this index as it has high overlap
            }
            else {
                ++it;
            }
        }
    }

    return picked;
}

// std::vector<int> nms(const std::vector<Detection>& detections, float nms_ths) {
//     std::vector<int> indices;
//     // Your NMS implementation goes here
//     return indices;
// }

Ort::Session* get_model(Ort::Env* env, const wchar_t* path) {
    //set any option (e.g. GPU ID)
    Ort::SessionOptions session_options;
    session_options.AppendExecutionProvider_CUDA(0);

    return new Ort::Session(*env, path, session_options);
}

float* inf_post(Ort::Session* model, std::vector<unsigned char>* inputs_value) {
    int num_classes = 10;
    float conf_ths = 0.5
        float nms_ths = 0.45

        std::vector<int64_t> shape = { 1, 800, 1440, 3 };
    std::vector<const char*> names_input = { "images" };
    std::vector<const char*> names_output = { "outputs" };
    // long long* shape=new long long[4]{1,800,1440,3};
    // const char** names_input=new const char* [1]{"images"};
    // const char** names_output=new const char* [1]{"outputs"};
    Ort::Value input_tensor = Ort::Value::CreateTensor<unsigned char>(
        Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault), inputs_value->data(), inputs_value->size(), shape, 4);

    Ort::Value output_tensor = model->Run(Ort::RunOptions(nullptr), names_input.data(), &input_tensor, 1, names_output.data(), 1)[0];
    float* outputs = output_tensor.GetTensorMutableData<float>();
    std::vector<int64_t> output_shape = output_tensor.GetTensorTypeAndShapeInfo().GetShape();

    int num_detections = static_cast<int>(output_shape[1]);

    // float* outputs=model->Run(Ort::RunOptions(nullptr),names_input,&input_tensor,1,names_output,1)[0].GetTensorMutableData<float>();

    // num_detections * [cx, cy, w, h, conf, class1_score, ..., classN_score]

    std::vector<Detection> detections;
    for (int i = 0; i < num_detections; ++i) {
        float* base = outputs + i * (5 + num_classes);
        float cx = base[0];
        float cy = base[1];
        float w = base[2];
        float h = base[3];
        float obj_score = base[4];

        float max_cscore = -1.0;
        int max_class = -1;
        for (int j = 0; j < num_classes; ++j) {
            float class_score = base[5 + j];
            if (class_score > max_cscore) {
                max_cscore = class_score;
                max_class = j;
            }

            if (obj_score * max_cscore > conf_ths) {
                float x = cx - w / 2;
                float y = cy - h / 2;
                float x2 = cx + w / 2;
                float y2 = cy + h / 2;
                detections.push_back({ cv::Rect2f(x, y, x2 - x, y2 - y), obj_score * max_cscore, max_class });
            }
        }
    }

    auto selected_dets = nms(detections, nms_ths);

    
    return [0,0];
}

int main(void) {
    std::vector<unsigned char>* inputs_value = new std::vector<unsigned char>(3 * 800 * 1440, 255);
    float* outputs;
    Ort::Env env;
    Ort::Session* model = get_model(&env, L"./model.onnx");
    while (true) {
        outputs = inf_post(model, inputs_value);
        std::cout << outputs[0] << std::endl;
    }
}
 

C++ Online Compiler

Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++ and start coding!

Read inputs from stdin

OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.

#include <iostream>
#include <string>
using namespace std;

int main() 
{
    string name;
    cout << "Enter name:";
    getline (cin, name);
    cout << "Hello " << name;
    return 0;
}

About C++

C++ is a widely used middle-level programming language.

  • Supports different platforms like Windows, various Linux flavours, MacOS etc
  • C++ supports OOPS concepts like Inheritance, Polymorphism, Encapsulation and Abstraction.
  • Case-sensitive
  • C++ is a compiler based language
  • C++ supports structured programming language
  • C++ provides alot of inbuilt functions and also supports dynamic memory allocation.
  • Like C, C++ also allows you to play with memory using Pointers.

Syntax help

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition If-Else is used.

if(conditional-expression) {
   //code
}
else {
   //code
}

You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to If-Else-If ladder.

switch(conditional-expression){    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
......    
    
default:     
 code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
  //code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while (condition) {  
// code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {  
 // code 
} while (condition); 

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.

How to declare a Function:

return_type function_name(parameters);

How to call a Function:

function_name (parameters)

How to define a Function:

return_type function_name(parameters) {  
 // code
}