#include
#include
#include
using namespace std;
using namespace cv::dnn;
using namespace cv;
String Model_Caffe = "bvlc_googlenet.caffemodel";//Caffe模型
String Model_Text = "vblc_googlener.prototxt";//描述文件
String Label_Text = "synset_words.txt";//标签文件
vector readClassLabels();//读取标签
//https://blog.csdn.net/Daker_Huang/article/details/86736072
int main(int argc, char** argv)
{
vector labels = readClassLabels();
Mat src;
src = imread("../path.jpg");
if (src.empty())
{
cout << "could not load image..." << endl;
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
Net caffe_net = readNetFromCaffe(Model_Text, Model_Caffe);//读取Caffe模型
if (caffe_net.empty())
{
cout << "could not load Caffe_net..." << endl;
return -2;
}
//blobFromImage主要是用来对图片进行预处理:①整体像素值减去平均值(mean)②通过缩放系数(Scalefactor)对图片像素值进行缩放
double Scalefactor = 1.0;
Mat InputBlob = blobFromImage(src, //输入神经网络进行处理或者分类的图片
Scalefactor, //图片减去平均值之后,对剩下的像素值进行一定的尺度缩放
Size(224, 224),//神经网络在训练的时候要求输入的图片尺寸
Scalar(104, 117, 123));//mean需要将图片整体减去的平均值,如果我们需要对RGB图片的三个通道分别减去不同的值,那么可以使用3组平均值
Mat prob;
//"vblc_googlener.prototxt"文件中 卷积第一层是data
for (int i = 0; i < 10; i++)
{
caffe_net.setInput(InputBlob, "data");//bvlc_googlenet.caffemodel中第一个layer_name
prob = caffe_net.forward("prob");//bvlc_googlenet.caffemodel中最后一个layer_name
}
Mat Matprob = prob.reshape(1, 1);//维度变成1*1000s
double Probability;//最大相似度
Point classindex;
minMaxLoc(Matprob, NULL, &Probability, NULL, &classindex);//返回最大值
int Nameindex = classindex.x;//最大相似度对应的索引
cout << "最大相似度Probability:" << Probability * 10 << "%" << endl;
cout << "标签名NameValue:" << labels.at(Nameindex) << endl;
putText(src,labels.at(Nameindex),Point(20,20),FONT_HERSHEY_SIMPLEX,0.5, Scalar(0, 0, 255), 1, 8);
imshow("src", src);
waitKey(0);
return 0;
}
vector readClassLabels()
{
ifstream fp(Label_Text);//打开"synset_words.text"标签文件
if (!fp.is_open())//判断fp是否成功读取文件
{
cout << "文件没找到" << endl;
exit(-1);//判断语句
}
vector classNames;//存放name
string name;
while (!fp.eof())//当文件没有读到尾部
{
getline(fp, name);//从fp中读取文件的每一行,并将结果放到name中
if (name.length())
{
classNames.push_back(name.substr(name.find(" ") + 1));//空格+1后面的字符返回给name,并写入classNames
//substr(开始,长度),并返回子串//如果没有指定长度,则子字符串将延续到源字符串的结尾
}
}
fp.close();//关闭输入输出流
return classNames;
}
输出结果: