#ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #include <iostream> #include <fstream> #include <opencv2/dnn/dnn.hpp> #include <highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; using namespace cv::dnn; string model_txt = "bvlc_googlenet.prototxt"; String model_bin = "bvlc_googlenet.caffemodel"; string label_file = "synset_words.txt"; // 类别标签表 vector<String> readLabels(); int main(int argc, char* argv[]) { // 1.加载图片 Mat src = imread("test1.jpg"); if (src.empty()) { cout << "The image is empty, please check it." << endl; return -1; } imshow("test1", src); // 2.加载caffe模型 Net net = readNetFromCaffe(model_txt, model_bin); if (net.empty()) { cout << "load net model data failed..." << endl; return -1; } // 3.读入分类标签 vector<String> labels = readLabels(); // 4.将输入图像转换成GoogleNet可识别的blob格式 Mat inputblob = blobFromImage(src, 1.0, Size(224, 224), Scalar(255, 0, 0)); // 5.预测 Mat prob_result; for (int i = 0; i < 10; i++) { // 进行10次预测,取可能性最大的类别 net.setInput(inputblob, "data"); prob_result = net.forward("prob"); } Mat probMat = prob_result.reshape(1, 1); // 1-channel,1-rows, 变成1行10列 Point class_position; double class_probability; minMaxLoc(probMat, NULL, &class_probability, NULL, &class_position); // 找出最大的可能性及其位置 // 打印最大可能性的值 int classidx = class_position.x; printf(" current image classification : %s, possible : %.2f", labels.at(classidx).c_str(), class_probability); // 在图上打印类别 putText(src, labels.at(classidx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8); imshow("Image Classification", src); waitKey(); return 0; } vector<String> readLabels() { vector<String> classNames; ifstream in(label_file); if (!in.is_open()) { cout << "标签文件不能打开" << endl; exit(-1); } string name; while (!in.eof())// 直至到达文件尾 { getline(in, name); // 读取一行 if (!name.empty()) { // 将描述分类前的数字去掉 classNames.push_back(name.substr(name.find(' ') + 1));// 复制制定位置、长度的子字符串 } } in.close(); return classNames; }