本文主要说明如何通过C++接口实现ssd多目标识别的演示。
1.前期准备工作
预先安装,编译caffe,具体可以参考https://blog.csdn.net/u012986684/article/details/72469542。此篇文章有详细的安装编译教程。
2.编译遇到问题
在编译过程中,总会出现这样或者那样的问题。推荐两篇教程帮助大家解决问题。https://blog.csdn.net/jjprincess/article/details/79613432,https://blog.csdn.net/m0_37407756/article/details/70789271。
3.实例运行
对于ssd网络模型,系统提供了c++接口以及python接口,大多数文章关于python的接口,本篇文章主要讲解c++如何进行model训练以及运行demo。
首先,打开/caffe/examples/ssd,在文件夹内有ssd_detect.cpp,ssd_detect.py,分别是c++以及python的运行实例。
打开ssd_detect.cpp,代码如下:
// This is a demo code for using a SSD model to do detection.
// The code is modified from examples/cpp_classification/classification.cpp.
// Usage:
// ssd_detect [FLAGS] model_file weights_file list_file
//
// where model_file is the .prototxt file defining the network architecture, and
// weights_file is the .caffemodel file containing the network parameters, and
// list_file contains a list of image files with the format as follows:
// folder/img1.JPEG
// folder/img2.JPEG
// list_file can also contain a list of video files with the format as follows:
// folder/video1.mp4
// folder/video2.mp4
//
#include <caffe/caffe.hpp>
#ifdef USE_OPENCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#endif // USE_OPENCV
#include <algorithm>
#include <iomanip>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifdef USE_OPENCV
using namespace caffe; // NOLINT(build/namespaces)
class Detector {
public:
Detector(const string& model_file,
const string& weights_file,
const string& mean_file,
const string& mean_value);
std::vector<vector<float> > Detect(const cv::Mat& img);
private:
void SetMean(const string& mean_file, const string& mean_value);
void WrapInputLayer(std::vector<cv::Mat>* input_channels);
void Preprocess(const cv::Mat& img,
std::vector<cv::Mat>* input_channels);
private:
shared_ptr<Net<float> > net_;
cv::Size input_geometry_;
int num_channels_;
cv::Mat mean_;
};
Detector::Detector(const string& model_file,
const string& weights_file,
const string& mean_file,
const string& mean_value) {
#ifdef CPU_ONLY
Caffe::set_mode(Caffe::CPU);
#else
Caffe::set_mode(Caffe::GPU);
#endif
/* Load the network. */
net_.reset(new Net<float>(model_file, TEST));
net_->CopyTrainedLayersFrom(weights_file);
CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input.";
CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output.";
Blob<float>* input_layer = net_->input_blobs()[0];
num_channels_ = input_layer->