Use el módulo opencv3.3DNN para llamar al modelo de café entrenado en vs para la clasificación

Cómo usar caffe para entrenar al clasificador, consulte este blog https://blog.csdn.net/sinat_41852207/article/details/88194744

 Necesidad: modelo entrenado por Caffe y el archivo de configuración de prueba correspondiente deploy.prototxt,

Un archivo txt con un nombre de imagen

Un archivo label.txt, que contiene el nombre de la categoría.

Finalmente, coloque las imágenes clasificadas en diferentes carpetas para una fácil inspección. 

//从文件夹批量读取图片,用caffemodel测试分类效果
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>

using namespace cv;
using namespace cv::dnn;
using namespace std;
String modelTxt = "D:/software_engineer/caffe-master/examples/testImg/deploy.prototxt";//caffe的测试网络结构模型
String modelBin = "D:/software_engineer/caffe-master/examples/testImg/cifar10_quick_iter_10000.caffemodel";//caffe训练好的文件
String labelFile = "D:/software_engineer/caffe-master/examples/testImg/labels.txt";//训练的时候用0和1表示类别,利用这个文件把0和1对应到OK和NG
string ImgFile = "D:/images/total/imgName.txt";////从该txt文件读取图片名,txt里面是图片名 如10.jpg
string saveRoadOK = "D:/images/OK/" ;//最后输出保存OK图片的路径
string saveRoadNG = "D:/images/NG/" ;//最后输出保存NG图片的路径,我是二分类,所以输出为两个文件

vector<String> readClasslabels();

int main(int argc, char** argv) {
	ifstream fin(ImgFile, ios::in);
	//char line[1024] = { 0 };
	string line;
	while (getline(fin, line))
	{
		cout << "Image Name: " << line << endl;
		string imgRoad = "D:/images/total/" + line;//图片的绝对路径名
		Mat testImage = imread(imgRoad);
		if (testImage.empty()) 
		{
			printf("could not load image...\n");
			waitKey(0);
			return -1;
		}
		// create lenet with caffemodel text and bin
		Net net = readNetFromCaffe(modelTxt, modelBin);
		if (net.empty())
		{
			cerr << "Can't load network by using the following files: " << endl;
			cerr << "prototxt:   " << modelTxt << endl;
			cerr << "caffemodel: " << modelBin << endl;
			return -1;
		}
		// 读取分类数据
		vector<String> labels = readClasslabels();
		Mat inputBlob = blobFromImage(testImage, 1.0, Size(32, 32), Scalar(0, 0, 0));//size为32*32由训练模型确定,后一个参数为减均值操作,这里我没有减均值
		Mat prob;
		net.setInput(inputBlob, "data");//“data”是deploy.prototxt里第一层名字
		// 分类预测
		prob = net.forward("prob");//“prob”是deploy.prototxt里最后一层名字
		// 读取分类索引,最大与最小值
		Mat probMat = prob.reshape(1, 1); 
		Point classNumber;
		double classProb;
		minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一个
		int classIdx = classNumber.x; // 分类索引号
		//printf("\n current image classification : %s, possible : %.2f \n", labels.at(classIdx).c_str(), classProb);
		string className = labels.at(classIdx);//类名(ok ng)               .c_str()
		cout << "current image classification :"<<className << endl;
		printf("---------------------------------------------------------\n");
		if (className=="OK")
		{
			imwrite(saveRoadOK + line, testImage);
		}
		else
		{
			imwrite(saveRoadNG + line, testImage);
		}
		putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);//在图片上写字
		imshow("Image Category", testImage);
	}
	fin.clear();
	fin.close();
	waitKey(0);
	return 0;
}
// 读取图像的1000个分类标记文本数据 
vector<String> readClasslabels() {
	vector<String> classNames;
	ifstream fp(labelFile);
	if (!fp.is_open())
	{
		cerr << "File with classes labels not found: " << labelFile << endl;
		exit(-1);
	}
	string name;
	while (!fp.eof())
	{
		getline(fp, name);
		if (name.length())
			classNames.push_back(name.substr(name.find(' ') + 1));
	}
	fp.close();
	return classNames;
}




El resultado final: 

 

Publicado 59 artículos originales · Me gusta46 · Visitas 30,000+

Supongo que te gusta

Origin blog.csdn.net/sinat_41852207/article/details/88197593
Recomendado
Clasificación