//    This file is part of Motion Watch.

//    Motion Watch is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.

//    Motion Watch is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

#include "obj_detect.h"

bool objectInImage(const Mat &src, const Rect &area, shared_t *share)
{
    // reference: https://github.com/doleron/yolov5-opencv-cpp-python/blob/main/cpp/yolo.cpp
    Mat blockImage(src, area);
    Mat blob;

    dnn::blobFromImage(blockImage, blob, 1./255., Size(area.width, area.height), cv::Scalar(), true, false);

    share->network.setInput(blob);

    vector<Mat> outputs;

    share->network.forward(outputs, share->network.getUnconnectedOutLayersNames());

    float *data = (float *)outputs[0].data;

    share->stat << "object_detection---" << endl;
    share->stat << "     outputs_size=" << outputs.size() << " looking_for_objects..." << endl;

    for (int i = 0; i < 25200; ++i)
    {
        // confidence level data[4];
        if (data[4] >= 0.4)
        {
            float *classesScores = data + 5;

            Mat    scores(1, share->classNames.size(), CV_32FC1, classesScores);
            Point  classId;
            double maxClassScore;

            minMaxLoc(scores, 0, &maxClassScore, 0, &classId);

            share->stat << "     potential_object[confidence_level]=" << data[4] << endl;
            share->stat << "     potential_object[class_score]=" << maxClassScore << endl;

            if (maxClassScore > 0.2)
            {
                share->stat << "     object_confirmed" << endl;

                return true;
            }
        }

        data += 85;
    }

    share->stat << "     no_objects_found" << endl;

    return false;
}
