caffe - - 在windows上实施 前向

2024-08-23 13:58
文章标签 windows 实施 caffe 前向

本文主要是介绍caffe - - 在windows上实施 前向,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

caffe-window搭建自己的小项目例子

           手头有一个实际的视觉检测的项目,用的是caffe来分类,于是需要用caffe新建自己的项目的例子。在网上找了好久都没有找到合适的,于是自己开始弄。

1 首先是配置caffe的VC++目录中的include和库文件。配置include lib dll都是坑,而且还分debug和release两个版本。添加输入项目需要注意,而且需要把编译好的caffe.lib等等一系列东西拷贝到当前项目下。也就是caffe bulid文件夹下面的东西,包括caffe.lib 、libcaffe.lib、还有很多dll.

这个是debug_include配置图

这个是debug_lib配置图

这个是release_include配置图

这个是release_lib配置图

同时也需要在,项目属性页的链接器输入中,填写相应的lib,其中debug和release是不同的。以下是需要填写的相应lib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//debug
opencv_calib3d2413d.lib
opencv_contrib2413d.lib
opencv_core2413d.lib
opencv_features2d2413d.lib
opencv_flann2413d.lib
opencv_gpu2413d.lib
opencv_highgui2413d.lib
opencv_imgproc2413d.lib
opencv_legacy2413d.lib
opencv_ml2413d.lib
opencv_objdetect2413d.lib
opencv_ts2413d.lib
opencv_video2413d.lib
caffe.lib
libcaffe.lib
cudart.lib
cublas.lib
curand.lib
gflagsd.lib
libglog.lib
libopenblas.dll.a
libprotobuf.lib
leveldb.lib
hdf5.lib
hdf5_hl.lib
Shlwapi.lib
//release
opencv_calib3d2413.lib
opencv_contrib2413.lib
opencv_core2413.lib
opencv_features2d2413.lib
opencv_flann2413.lib
opencv_gpu2413.lib
opencv_highgui2413.lib
opencv_imgproc2413.lib
opencv_legacy2413.lib
opencv_ml2413.lib
opencv_objdetect2413.lib
opencv_ts2413.lib
opencv_video2413.lib
caffe.lib
libcaffe.lib
cudart.lib
cublas.lib
curand.lib
gflags.lib
libglog.lib
libopenblas.dll.a
libprotobuf.lib
leveldb.lib
lmdb.lib
hdf5.lib
hdf5_hl.lib
Shlwapi.lib

 2 新建一个Classifier的c++类,其中头文件为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "stdafx.h"
#include <caffe caffe.hpp="">
#include <opencv2 core="" core.hpp="">
#include <opencv2 highgui="" highgui.hpp="">
#include <opencv2 imgproc="" imgproc.hpp="">
#include <algorithm>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#pragma once
using  namespace  caffe;   // NOLINT(build/namespaces)
using  std::string;
//using namespace boost; 注意不需要添加这个
/* Pair (label, confidence) representing a prediction. */
typedef  std::pair<string,  float = "" > Prediction;
class  Classifier
{
public :
     Classifier( const  string& model_file,
         const  string& trained_file,
         const  string& mean_file,
         const  string& label_file);
     std::vector<prediction> Classify( const  cv::Mat& img,  int  N = 5);
     ~Classifier();
private :
     void  SetMean( const  string& mean_file);
     std::vector< float > Predict( const  cv::Mat& img);
     void  WrapInputLayer(std::vector<cv::mat>* input_channels);
     void  Preprocess( const  cv::Mat& img,
         std::vector<cv::mat>* input_channels);
private :
     boost::shared_ptr<net< float > > net_;
     cv::Size input_geometry_;
     int  num_channels_;
     cv::Mat mean_;
     std::vector<string> labels_;
};
</string></net< float ></cv::mat></cv::mat></ float ></prediction></string,></vector></utility></string></memory></iosfwd></algorithm></opencv2></opencv2></opencv2></caffe>

  c++文件为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "stdafx.h"
#include "Classifier.h"
Classifier::Classifier( const  string& model_file,
     const  string& trained_file,
     const  string& mean_file,
     const  string& label_file) {
#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(trained_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->channels();
     CHECK(num_channels_ == 3 || num_channels_ == 1)
         <<  "Input layer should have 1 or 3 channels." ;
     input_geometry_ = cv::Size(input_layer->width(), input_layer->height());
     /* Load the binaryproto mean file. */
     SetMean(mean_file);
     /* Load labels. */
     std::ifstream labels(label_file.c_str());
     CHECK(labels) <<  "Unable to open labels file "  << label_file;
     string line;
     while  (std::getline(labels, line))
         labels_.push_back(string(line));
     Blob< float >* output_layer = net_->output_blobs()[0];
     CHECK_EQ(labels_.size(), output_layer->channels())
         <<  "Number of labels is different from the output layer dimension." ;
}
static  bool  PairCompare( const  std::pair< float int >& lhs,
     const  std::pair< float int >& rhs) {
     return  lhs.first > rhs.first;
}
/* Return the indices of the top N values of vector v. */
static  std::vector< int > Argmax( const  std::vector< float >& v,  int  N) {
     std::vector<std::pair< float int > > pairs;
     for  ( size_t  i = 0; i < v.size(); ++i)
         pairs.push_back(std::make_pair(v[i],  static_cast < int >(i)));
     std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end(), PairCompare);
     std::vector< int > result;
     for  ( int  i = 0; i < N; ++i)
         result.push_back(pairs[i].second);
     return  result;
}
/* Return the top N predictions. */
std::vector<Prediction> Classifier::Classify( const  cv::Mat& img,  int  N) {
     std::vector< float > output = Predict(img);
     N = std::min< int >(labels_.size(), N);
     std::vector< int > maxN = Argmax(output, N);
     std::vector<Prediction> predictions;
     for  ( int  i = 0; i < N; ++i) {
         int  idx = maxN[i];
         predictions.push_back(std::make_pair(labels_[idx], output[idx]));
     }
     return  predictions;
}
/* Load the mean file in binaryproto format. */
void  Classifier::SetMean( const  string& mean_file) {
     BlobProto blob_proto;
     ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
     /* Convert from BlobProto to Blob<float> */
     Blob< float > mean_blob;
     mean_blob.FromProto(blob_proto);
     CHECK_EQ(mean_blob.channels(), num_channels_)
         <<  "Number of channels of mean file doesn't match input layer." ;
     /* The format of the mean file is planar 32-bit float BGR or grayscale. */
     std::vector<cv::Mat> channels;
     float * data = mean_blob.mutable_cpu_data();
     for  ( int  i = 0; i < num_channels_; ++i) {
         /* Extract an individual channel. */
         cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
         channels.push_back(channel);
         data += mean_blob.height() * mean_blob.width();
     }
     /* Merge the separate channels into a single image. */
     cv::Mat mean;
     cv::merge(channels, mean);
     /* Compute the global mean pixel value and create a mean image
     * filled with this value. */
     cv::Scalar channel_mean = cv::mean(mean);
     mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);
}
std::vector< float > Classifier::Predict( const  cv::Mat& img) {
     Blob< float >* input_layer = net_->input_blobs()[0];
     input_layer->Reshape(1, num_channels_,
         input_geometry_.height, input_geometry_.width);
     /* Forward dimension change to all layers. */
     net_->Reshape();
     std::vector<cv::Mat> input_channels;
     WrapInputLayer(&input_channels);
     Preprocess(img, &input_channels);
     net_->Forward();
     /* Copy the output layer to a std::vector */
     Blob< float >* output_layer = net_->output_blobs()[0];
     const  float * begin = output_layer->cpu_data();
     const  float * end = begin + output_layer->channels();
     return  std::vector< float >(begin, end);
}
/* Wrap the input layer of the network in separate cv::Mat objects
* (one per channel). This way we save one memcpy operation and we
* don't need to rely on cudaMemcpy2D. The last preprocessing
* operation will write the separate channels directly to the input
* layer. */
void  Classifier::WrapInputLayer(std::vector<cv::Mat>* input_channels) {
     Blob< float >* input_layer = net_->input_blobs()[0];
     int  width = input_layer->width();
     int  height = input_layer->height();
     float * input_data = input_layer->mutable_cpu_data();
     for  ( int  i = 0; i < input_layer->channels(); ++i) {
         cv::Mat channel(height, width, CV_32FC1, input_data);
         input_channels->push_back(channel);
         input_data += width * height;
     }
}
void  Classifier::Preprocess( const  cv::Mat& img,
     std::vector<cv::Mat>* input_channels) {
     /* Convert the input image to the input image format of the network. */
     cv::Mat sample;
     if  (img.channels() == 3 && num_channels_ == 1)
         cv::cvtColor(img, sample, cv::COLOR_BGR2GRAY);
     else  if  (img.channels() == 4 && num_channels_ == 1)
         cv::cvtColor(img, sample, cv::COLOR_BGRA2GRAY);
     else  if  (img.channels() == 4 && num_channels_ == 3)
         cv::cvtColor(img, sample, cv::COLOR_BGRA2BGR);
     else  if  (img.channels() == 1 && num_channels_ == 3)
         cv::cvtColor(img, sample, cv::COLOR_GRAY2BGR);
     else
         sample = img;
     cv::Mat sample_resized;
     if  (sample.size() != input_geometry_)
         cv::resize(sample, sample_resized, input_geometry_);
     else
         sample_resized = sample;
     cv::Mat sample_float;
     if  (num_channels_ == 3)
         sample_resized.convertTo(sample_float, CV_32FC3);
     else
         sample_resized.convertTo(sample_float, CV_32FC1);
     cv::Mat sample_normalized;
     cv::subtract(sample_float, mean_, sample_normalized);
     /* This operation will write the separate BGR planes directly to the
     * input layer of the network because it is wrapped by the cv::Mat
     * objects in input_channels. */
     cv::split(sample_normalized, *input_channels);
     CHECK( reinterpret_cast < float *>(input_channels->at(0).data)
         == net_->input_blobs()[0]->cpu_data())
         <<  "Input channels are not wrapping the input layer of the network." ;
}
Classifier::~Classifier()
{
}

  c++,文件来自于\caffe-master\examples\cpp_classification中的classification.cpp文件

3 直接编译后会出现的问题是F0519 14:54:12.494139 14504 layer_factory.hpp:77] Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type: Input (known types: Input ),百度后发现是要加头文件!http://blog.csdn.net/fangjin_kl/article/details/50936952#0-tsina-1-63793-397232819ff9a47a7b7e80a40613cfe1

因此安装上面说的新建一个head.h    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "caffe/common.hpp"
#include "caffe/layers/input_layer.hpp"
#include "caffe/layers/inner_product_layer.hpp"
#include "caffe/layers/dropout_layer.hpp"
#include "caffe/layers/conv_layer.hpp"
#include "caffe/layers/relu_layer.hpp"
#include "caffe/layers/pooling_layer.hpp"
#include "caffe/layers/lrn_layer.hpp"
#include "caffe/layers/softmax_layer.hpp"
namespace  caffe
{
     extern  INSTANTIATE_CLASS(InputLayer);
     extern  INSTANTIATE_CLASS(InnerProductLayer);
     extern  INSTANTIATE_CLASS(DropoutLayer);
     extern  INSTANTIATE_CLASS(ConvolutionLayer);
     REGISTER_LAYER_CLASS(Convolution);
     extern  INSTANTIATE_CLASS(ReLULayer);
     REGISTER_LAYER_CLASS(ReLU);
     extern  INSTANTIATE_CLASS(PoolingLayer);
     REGISTER_LAYER_CLASS(Pooling);
     extern  INSTANTIATE_CLASS(LRNLayer);
     REGISTER_LAYER_CLASS(LRN);
     extern  INSTANTIATE_CLASS(SoftmaxLayer);
     REGISTER_LAYER_CLASS(Softmax);
}

注意上述网络可能不全,需要根据实际的网络添加层。参考

 

  View Code

 

 

 

4 出现的第二个问题是有些符号GLOG_NO_ABBREVIATED_SEVERITIES未定义,因此在项目属性页 c++预处理器中添加下面两个:

GLOG_NO_ABBREVIATED_SEVERITIES
_SCL_SECURE_NO_WARNINGS

5 同时需要把

#include <caffe/proto/caffe.pb.h>
#include "head.h"

这两个头文件放到stdafx.h中,必须放到里面。

6 编译通过后,编写测试分类的程序,首先加载caffermodle.

string model_file = "D:\\caffe\\caffe-master\\mypower\\deploy.prototxt";//prototxt 这个必须是depoly,这个是计算输出的类别概率
string trained_file = "D:\\caffe\\caffe-master\\mypower_iter_2000.caffemodel"; //这个是训练好的model
string mean_file = "D:\\caffe\\caffe-master\\mypower\\imagenet_mean.binaryproto";//这个是均值文件
string label_file ="D:\\caffe\\caffe-master\\mypower\\label.txt"; //这个是样本标签 ,如果两类,可以新建一个txt文件,里面写作如下

1
2
0 good
1 bad

定义一个指针  Classifier *classifier;
classifier = new Classifier(model_file, trained_file, mean_file, label_file);

 分类程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cv::Mat img(roiimage, 0); //加载图像
  //CHECK(!img.empty()) << "Unable to decode image " ;
  std::vector<Prediction> predictions = classifier->Classify(img);
  /* Print the top N predictions. */
  string precision_p0= "" ;
  for  ( size_t  i = 0; i < predictions.size()-1; ++i) //只输出了概率最大的那一类,通常就是第一类
  {
   Prediction p = predictions[i];
   precision_p0 = p.first;
   std::cout << std::fixed << std::setprecision(4) << p.second <<  " - \""
   << p.first <<  "\""  << std::endl;<br>   }
  char  firstc = precision_p0[0];
  if  (firstc ==  '0' ) //第一类正样本 好的<br>   {
   //AfxMessageBox("good");           
  }
  else  //第二类负样本 存在缺陷
  {
   //AfxMessageBox("bad");        
}

这篇关于caffe - - 在windows上实施 前向的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099572

相关文章

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

Python使用pysmb库访问Windows共享文件夹的详细教程

《Python使用pysmb库访问Windows共享文件夹的详细教程》本教程旨在帮助您使用pysmb库,通过SMB(ServerMessageBlock)协议,轻松连接到Windows共享文件夹,并列... 目录前置条件步骤一:导入必要的模块步骤二:配置连接参数步骤三:实例化SMB连接对象并尝试连接步骤四:

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

Windows如何添加右键新建菜单

Windows如何添加右键新建菜单 文章目录 Windows如何添加右键新建菜单实验环境缘起以新建`.md`文件为例第一步第二步第三步 总结 实验环境 Windows7 缘起 因为我习惯用 Markdown 格式写文本,每次新建一个.txt后都要手动修改为.md,真的麻烦。如何在右键新建菜单中添加.md选项呢? 网上有很多方法,这些方法我都尝试了,要么太麻烦,要么不凑效

Windows下Nginx的安装及开机启动

1、将nginx-1.16.1.zip解压拷贝至D:\web\nginx目录下。 2、启动Nginx,两种方法: (1)直接双击nginx.exe,双击后一个黑色的弹窗一闪而过。 (2)打开cmd命令窗口,切换到nginx目录下,输入命令 nginx.exe 或者 start nginx ,回车即可。 3、检查nginx是否启动成功。 直接在浏览器地址栏输入网址 http://lo