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;