RetinaFace:C++调用caffemodel的极简例程

RetinaFace的人脸检测模型,据说性价比优于MTCNN,想做成dll让其他部分调用(虽然dll还不会做)

今天实现了C++调用,不需要安装caffe,也不需要CUDA,装个opencv4.0+就可以了。

需要的有:

  • Windows10
  • vs2017
  • opencv4.2.0

1、新建项目,配置opencv库

vs2017里面Visual C++新建项目,空项目。

我一般习惯把opencv安装在C:/opencv/里面,opencv的安装包文件名是:opencv-4.2.0-vc14_vc15.exe,安装到C:/opencv/

解压结束以后添加系统环境变量:C:\opencv\opencv\build\x64\vc14\libC:\opencv\opencv\build\x64\vc14\libC:\opencv\opencv\build\x64\vc14\lib

给空项目配置opencv库:

a、项目使用Release x64

b、常规:平台工具集->Visual Studio 2017 (v141)

c、VC++目录->包含目录->C:\opencv\opencv\build\include\opencv2

d、VC++目录->库目录->C:\opencv\opencv\build\x64\vc14\lib

e、链接器 -> 输入 -> 附加依赖项 -> opencv_world420.lib

f、然后把这4个文件复制到main.cpp同级目录:

  • opencv_world420.dll
  • opencv_world420.pdb
  • opencv_world420d.dll
  • opencv_world420d.pdb

2、编写main.cpp

需要注意的点:

  • 准备好deploy.prototxtWiderface-RetinaFace.caffemodel
  • 解析net.forward的结果费了我好大的功夫
#include 
#include 
#include 
#include 
using namespace cv;
using namespace cv::dnn;
#include 
#include 
#include 
using namespace std;
int main()
{
	CV_TRACE_FUNCTION();
	String modelTxt = "deploy.prototxt";
	String modelBin = "Widerface-RetinaFace.caffemodel";
	String imageFile = "image_F1.jpg";
	Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
	if (net.empty())
	{
		std::cerr << "Can't load network by using the following files: " << std::endl;
		std::cerr << "prototxt:   " << modelTxt << std::endl;
		std::cerr << "caffemodel: " << modelBin << std::endl;
		exit(-1);
	}
	Mat img = imread(imageFile, cv::IMREAD_COLOR);
	int width = img.cols;
	int height = img.rows;
	int dims = img.channels();
	if (img.empty())
	{
		std::cerr << "Can't read image from the file: " << imageFile << std::endl;
		exit(-1);
	}
	//RetinaFaceNet accepts  640x640 RGB-images
	Mat inputBlob = blobFromImage(img, 1, Size(640, 640), Scalar(104, 117, 123));   //Convert Mat to batch of images
	Mat out;
	cv::TickMeter t;
	CV_TRACE_REGION("forward");
	net.setInput(inputBlob, "data");        //set the network input
	t.start();
	// out.shape = [1,1,200,7]
	out = net.forward("detection_out");     //compute output
	cv::Mat detectionMat(out.size[2], out.size[3], CV_32F, out.ptr());
	vector> bboxes;
	//TODO:优化循环
	for (int i = 0; i < detectionMat.rows; i++)
	{
		float confidence = detectionMat.at(i, 2);
		if (confidence > 0.7)
		{
			int x1 = static_cast(detectionMat.at(i, 3) * width);
			int y1 = static_cast(detectionMat.at(i, 4) * height);
			int x2 = static_cast(detectionMat.at(i, 5) * width);
			int y2 = static_cast(detectionMat.at(i, 6) * height);
			vector box = { x1, y1, x2, y2 };
			bboxes.push_back(box);
			cv::rectangle(img, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2, 4);
			//std::cout << x1 <<","<< y1<<"," << x2 <<","<< y2 << std::endl;
		}
	}
	//cv::imwrite("x.jpg", img);
	t.stop();
	std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
	system("pause");
	return 0;
}

最后生成一下解决方案就可以了,后面会生成dll了再回来补~

你可能感兴趣的:(深度学习)