Home > Mobile >  Wrong probability - OpenCV image classification
Wrong probability - OpenCV image classification

Time:12-04

I am trying to learn image classification using OpenCV and have started with this tutorial/guide https://learnopencv.com/deep-learning-with-opencvs-dnn-module-a-definitive-guide/

Just to test that everything works I downloaded the image code from the tutorial and everything work fine with no errors. I have used the exact same image as in the tutorial (a tiger picture). The problem is that they get a 91% match, whereas I only get 14%.

My guess is that something is missing in the code. Hence, in the guide, the python version of the same program used NumPy to get the probability. But I have really no clue.

The code in question is the following:

#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/dnn/all_layers.hpp>

using namespace std;
using namespace cv;
using namespace dnn;

int main(int, char**) {
    vector<string> class_names;
    ifstream ifs(string("../data/classification_classes_ILSVRC2012.txt").c_str());
    string line;
    while (getline(ifs, line)){
        class_names.push_back(line);
    }
    auto model = readNet("../data/DenseNet_121.prototxt",
                         "../data/DenseNet_121.caffemodel",
                         "Caffe");

    Mat image = imread("../data/tiger.jpg");
    Mat blob = blobFromImage(image, 0.01, Size(224, 224), Scalar(104, 117, 123));
    model.setInput(blob);
    Mat outputs = model.forward();
    double final_prob;
    minMaxLoc(outputs.reshape(1, 1), nullptr, &final_prob, nullptr, &classIdPoint);

    cout << final_prob;
}

Would really appreciate it if someone could help me!

CodePudding user response:

quoting from here :

From these, we are extracting the highest label index and storing it in label_id. However, these scores are not actually probability scores. We need to get the softmax probabilities to know with what probability the model predicts the highest-scoring label.

In the Python code above, we are converting the scores to softmax probabilities using np.exp(final_outputs) / np.sum(np.exp(final_outputs)). Then we are multiplying the highest probability score with 100 to get the predicted score percentage.

indeed, the c version of it does not do this, but you should get the same numerical result, if you use:

Mat outputs = model.forward();

Mat softmax;
cv::exp(outputs.reshape(1,1), softmax);
softmax /= cv::sum(softmax)[0];

double final_prob;
minMaxLoc(softmax, nullptr, &final_prob, nullptr, &classIdPoint);
final_prob *= 100;
  • Related