OpenCV4.1 Classification VS2017配置 错误及解决办法 与效果图

Table of Contents

下载所需档案

配置

第一步:OpenCV配置

第二步:错误: E1696 無法開啟 來源 檔案 "common.hpp"

第三步:错误:C4996 'getenv': This function or variable may be unsafe.

控制台参数

代码

效果图


下载所需档案

参考文章

https://docs.opencv.org/master/d5/de7/tutorial_dnn_googlenet.html

Firstly, download GoogLeNet model files: bvlc_googlenet.prototxt and bvlc_googlenet.caffemodel

Also you need file with names of ILSVRC2012 classes: classification_classes_ILSVRC2012.txt.

Put these files into working dir of this program example.

笔者翻译:

首先,下载GoogLeNet模型文件:bvlc_googlenet.prototxt和 bvlc_googlenet.caffemodel

还需要带有这个名字“ILSVRC2012”的分类文件 classification_classes_ILSVRC2012.txt

把这些文件放至程序的工作目录中。

我把它们都放置在E:/template文件夹下了,个人习惯

档案名称 下载地址 大小(KB)
bvlc_googlenet.prototxt

https://github.com/opencv/opencv_extra/blob/master/testdata/

dnn/bvlc_googlenet.prototxt

38
bvlc_googlenet.caffemodel http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel 52,280
classification_classes_ILSVRC2012.txt

https://github.com/opencv/opencv/blob/master/samples/

data/dnn/classification_classes_ILSVRC2012.txt

23

配置

第一步:OpenCV配置

请仔细看文章《OpenCV4.1 DNN Sample C++配置 VS2017 + Windows》

第二步:错误: E1696 無法開啟 來源 檔案 "common.hpp"

解决办法:

由于需要使用common.hpp文件,所以需要引入dnn目录到include中

我电脑上的路径为“D:\OpenCV\opencv410\sources\samples\dnn”

第三步:错误:C4996 'getenv': This function or variable may be unsafe.

C4996 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

解决办法:在C/C++ ->预处理中添加“_CRT_SECURE_NO_WARNINGS”即可

控制台参数

--model=e:/template/bvlc_googlenet.caffemodel --config=e:/template/bvlc_googlenet.prototxt --width=224 --height=224 --classes=e:/template/classification_classes_ILSVRC2012.txt --mean="104 117 123" --rgb --input=E:/template/images/dog1.jpg

也可以在控制台(cmd)中运行,如下图:

classification.exe --model=e:/template/bvlc_googlenet.caffemodel --config=e:/template/bvlc_googlenet.prototxt --width=224 --height=224 --classes=e:/template/classification_classes_ILSVRC2012.txt --mean="104 117 123" --rgb --input=E:/template/images/dog1.jpg

【注意】我把“--input=E:/template/images/cat1.jpg”放在了最后,因为方便修改图片名字

【注意】:从网页上直接复制这些参数可能会报下面的错误,我就遇到了,空格变成问号……

Error: Requested object was not found

解决办法:

把它们在Notepad++中正常写一遍再填入即可,每个“--”前是一个空格。

代码

OpenCV官网也有的,链接如下:

https://docs.opencv.org/master/d5/de7/tutorial_dnn_googlenet.html

注意事项:

1. 我的代码多了这行#include "pch.h",我是用Visual Studio建立的带有预编译头的项目不是空项目

2. #include "common.hpp"

这里面就三个函数,如下

我电脑上的路径为“D:\OpenCV\opencv410\sources\samples\dnn”

std::string genArgument(const std::string& argName, const std::string& help,
                        const std::string& modelName, const std::string& zooFile,
                        char key = ' ', std::string defaultVal = "");

std::string genPreprocArguments(const std::string& modelName, const std::string& zooFile);

std::string findFile(const std::string& filename);

3. 关于CommandLineParser,不会用的请参考这篇文章【强烈推荐的,这样更改图片时不用每次都重新build】

《OpenCV3 CommandLineParser类代码实例 使用说明 播放视频及效果图 VS2013控制台程序带参数的设定方法》

 

完整代码如下:

#include "pch.h"
#include <fstream>
#include <sstream>

#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

#include "common.hpp"

//控制台参数
std::string keys =
"{ help  h     | | Print help message. }"
"{ @alias      | | An alias name of model to extract preprocessing parameters from models.yml file. }"
"{ zoo         | models.yml | An optional path to file with preprocessing parameters }"
"{ input i     | | Path to input image or video file. Skip this argument to capture frames from a camera.}"
"{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }"
"{ classes     | | Optional path to a text file with names of classes. }"
"{ backend     | 0 | Choose one of computation backends: "
"0: automatically (by default), "
"1: Halide language (http://halide-lang.org/), "
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
"3: OpenCV implementation }"
"{ target      | 0 | Choose one of target computation devices: "
"0: CPU target (by default), "
"1: OpenCL, "
"2: OpenCL fp16 (half-float precision), "
"3: VPU }";

using namespace cv;
using namespace dnn;

std::vector<std::string> classes;

int main(int argc, char** argv)
{
	CommandLineParser parser(argc, argv, keys);

	const std::string modelName = parser.get<String>("@alias");
	const std::string zooFile = parser.get<String>("zoo");

	keys += genPreprocArguments(modelName, zooFile);

	parser = CommandLineParser(argc, argv, keys);
	parser.about("Use this script to run classification deep learning networks using OpenCV.");
	if (argc == 1 || parser.has("help"))
	{
		parser.printMessage();
		return 0;
	}

	float scale = parser.get<float>("scale");
	Scalar mean = parser.get<Scalar>("mean");
	bool swapRB = parser.get<bool>("rgb");
	int inpWidth = parser.get<int>("width");
	int inpHeight = parser.get<int>("height");
	String model = findFile(parser.get<String>("model"));
	String config = findFile(parser.get<String>("config"));
	String framework = parser.get<String>("framework");
	int backendId = parser.get<int>("backend");
	int targetId = parser.get<int>("target");

	// Open file with classes names.打开文件
	if (parser.has("classes"))
	{
		std::string file = parser.get<String>("classes");
		std::ifstream ifs(file.c_str());
		if (!ifs.is_open())
			CV_Error(Error::StsError, "File " + file + " not found");
		std::string line;
		while (std::getline(ifs, line))
		{
			classes.push_back(line);
		}
	}

	if (!parser.check())
	{
		parser.printErrors();
		return 1;
	}
	CV_Assert(!model.empty());


	Net net = readNet(model, config, framework);
	net.setPreferableBackend(backendId);
	net.setPreferableTarget(targetId);


	// Create a window创建一个窗口
	static const std::string kWinName = "Deep learning image classification in OpenCV";
	namedWindow(kWinName, WINDOW_NORMAL);

	//如果参数中有--input,就打开输入的图片,否则就打开摄像头
	VideoCapture cap;
	if (parser.has("input"))
		cap.open(parser.get<String>("input"));
	else
		cap.open(0);


	// Process frames.
	Mat frame, blob;
	while (waitKey(1) < 0)
	{
		cap >> frame;
		if (frame.empty())
		{
			waitKey();
			break;
		}
		blobFromImage(frame, blob, scale, Size(inpWidth, inpHeight), mean, swapRB, false);

		net.setInput(blob);
		Mat prob = net.forward();
		Point classIdPoint;
		double confidence;
		minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
		int classId = classIdPoint.x;


		// Put efficiency information.
		std::vector<double> layersTimes;
		double freq = getTickFrequency() / 1000;
		double t = net.getPerfProfile(layersTimes) / freq;
		std::string label = format("Inference time: %.2f ms", t);
		putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));

		// Print predicted class.
		label = format("%s: %.4f", (classes.empty() ? format("Class #%d", classId).c_str() :
			classes[classId].c_str()),
			confidence);
		putText(frame, label, Point(0, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));

		imshow(kWinName, frame);
	}
	return 0;
}

效果图

图片是从百度上搜的

识别结果有的正确,有的错误。

识别结果的准确率是依赖模型的,接下来我们可以考虑根据特定的情况、条件来训练特定模型。

以下识别所用时间不长,是因为我使用的Release版,Debug版时间会稍微久一些。

 

下面这张是官网图片,准确率还是很高的

 

 

我还特地找了一些漫画性质的猫,结果大家自己看吧

 

Pizza识别成golf ball~~

发布了85 篇原创文章 · 获赞 82 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/yl_best/article/details/98218985
今日推荐