本文假设你已经安装CUDA,CUDA版本是7.5。

1.编译caffe的Windows版本

happynear的博客已经介绍了如何在windows下编译caffe,这里把我自己编译的过程记录下来,也算是做做笔记,方便以后查看。

1.1下载caffe-windows-master

下载地址:caffe-windows-master

1.2下载第三方库

下载地址:3rdparty

1.3 解压

解压第三方库3rdparty,解压到caffe-windows-master中的3rdparty文件夹中,即caffe-windows-master/3rdparty中的内容为:
!!!然后,需要将bin文件夹加入环境变量中。
当然,如果嫌麻烦,下载我解压好的文件就行,跳过以上过程,下载该文件,下载地址:点击这里。

1.4 开始编译

双击caffe-windows-master\src\caffe\proto\extract_proto.bat,生成caffe.pb.hcaffe.pb.cc两个c++文件,和caffe_pb2.py这个python使用的文件。然后,用vs2013打开./buildVS2013/MainBuilder.sln,打开之后切换编译模式至Release X64模式。如果你的CUDA版本不是7.5,打开之后可能显示加载失败,这时就要用记事本打开./buildVS2013/MSVC/MainBuilder.vcxproj,搜索CUDA 7.5,把这个7.5换成你自己的CUDA版本,就可以正常打开了。
 右键caffelib项目,配置属性——>常规,将配置类型修改为应用程序(.exe),目标文件扩展名修改为.exe;接着:
C/C++ ——> 常规,附加包含目录修改如下(CUDA路径按自己的修改):
[plain] view plaincopy
  1. ../../3rdparty/include
  2. ../../src
  3. ../../include
  4. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include

链接器 ——> 常规,附加库目录修改如下(CUDA路径按自己的修改):

[plain] view plaincopy
  1. ../../3rdparty/lib
[plain] view plaincopy
  1. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64
链接器——>输入;将cudnn64_65.lib修改成cudnn.lib

如果需要matlab和python接口,可参考如下设置(路径按自己的设置):

Matcaffe项目:

附加包含目录:

[plain] view plaincopy
  1. ../../3rdparty/include
  2. ../../src
  3. ../../include
  4. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include
  5. D:\Program Files\MATLAB\R2014a\extern\include

附加库目录:

[plain] view plaincopy
  1. ../../3rdparty/lib
  2. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64
  3. D:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft

Pycaffe项目:

附加包含目录:

[plain] view plaincopy
  1. ../../3rdparty/include
  2. ../../src
  3. ../../include
  4. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include
  5. D:\Python27\include
  6. D:\Python27\Lib\site-packages\numpy\core\include

附加库目录:

[plain] view plaincopy
  1. ../../3rdparty/lib
  2. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64
  3. D:\Python27\libs

2.修改classification.cpp代码

右键caffelib,添加新建项classification.cpp,classification.cpp代码可参考如下:

该代码逐张读取文件夹下的图像并将分类结果显示在图像左上角,空格下一张。
结果显示在左上角,有英文和中文两种标签可选,如果显示中文,需要使用Freetype库,请自行百度。

[plain] view plaincopy
  1. #include <caffe/caffe.hpp>
  2. #include <opencv2/core/core.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/imgproc/imgproc.hpp>
  5. #include <iosfwd>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include <iostream>
  10. #include <string>
  11. #include <sstream>
  12. #include "CvxText.h" //英文标签去掉该头文件
  13. using namespace caffe;  // NOLINT(build/namespaces)
  14. using std::string;
  15. /* Pair (label, confidence) representing a prediction. */
  16. typedef std::pair<string, float> Prediction;
  17. class Classifier {
  18. public:
  19. Classifier(const string& model_file,
  20. const string& trained_file,
  21. const string& mean_file,
  22. const string& label_file);
  23. std::vector<Prediction> Classify(const cv::Mat& img, int N = 5);
  24. private:
  25. void SetMean(const string& mean_file);
  26. std::vector<float> Predict(const cv::Mat& img);
  27. void WrapInputLayer(std::vector<cv::Mat>* input_channels);
  28. void Preprocess(const cv::Mat& img,
  29. std::vector<cv::Mat>* input_channels);
  30. private:
  31. shared_ptr<Net<float> > net_;
  32. cv::Size input_geometry_;
  33. int num_channels_;
  34. cv::Mat mean_;
  35. std::vector<string> labels_;
  36. };
  37. Classifier::Classifier(const string& model_file,
  38. const string& trained_file,
  39. const string& mean_file,
  40. const string& label_file) {
  41. #ifdef CPU_ONLY
  42. Caffe::set_mode(Caffe::CPU);
  43. #else
  44. Caffe::set_mode(Caffe::GPU);
  45. #endif
  46. /* Load the network. */
  47. net_.reset(new Net<float>(model_file, TEST));
  48. net_->CopyTrainedLayersFrom(trained_file);
  49. CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input.";
  50. CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output.";
  51. Blob<float>* input_layer = net_->input_blobs()[0];
  52. num_channels_ = input_layer->channels();
  53. CHECK(num_channels_ == 3 || num_channels_ == 1)
  54. << "Input layer should have 1 or 3 channels.";
  55. input_geometry_ = cv::Size(input_layer->width(), input_layer->height());
  56. /* Load the binaryproto mean file. */
  57. SetMean(mean_file);
  58. /* Load labels. */
  59. std::ifstream labels(label_file);
  60. CHECK(labels) << "Unable to open labels file " << label_file;
  61. string line;
  62. while (std::getline(labels, line))
  63. labels_.push_back(string(line));
  64. Blob<float>* output_layer = net_->output_blobs()[0];
  65. CHECK_EQ(labels_.size(), output_layer->channels())
  66. << "Number of labels is different from the output layer dimension.";
  67. }
  68. static bool PairCompare(const std::pair<float, int>& lhs,
  69. const std::pair<float, int>& rhs) {
  70. return lhs.first > rhs.first;
  71. }
  72. /* Return the indices of the top N values of vector v. */
  73. static std::vector<int> Argmax(const std::vector<float>& v, int N) {
  74. std::vector<std::pair<float, int> > pairs;
  75. for (size_t i = 0; i < v.size(); ++i)
  76. pairs.push_back(std::make_pair(v[i], i));
  77. std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end(), PairCompare);
  78. std::vector<int> result;
  79. for (int i = 0; i < N; ++i)
  80. result.push_back(pairs[i].second);
  81. return result;
  82. }
  83. /* Return the top N predictions. */
  84. std::vector<Prediction> Classifier::Classify(const cv::Mat& img, int N) {
  85. std::vector<float> output = Predict(img);
  86. std::vector<int> maxN = Argmax(output, N);
  87. std::vector<Prediction> predictions;
  88. for (int i = 0; i < N; ++i) {
  89. int idx = maxN[i];
  90. predictions.push_back(std::make_pair(labels_[idx], output[idx]));
  91. }
  92. return predictions;
  93. }
  94. /* Load the mean file in binaryproto format. */
  95. void Classifier::SetMean(const string& mean_file) {
  96. BlobProto blob_proto;
  97. ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
  98. /* Convert from BlobProto to Blob<float> */
  99. Blob<float> mean_blob;
  100. mean_blob.FromProto(blob_proto);
  101. CHECK_EQ(mean_blob.channels(), num_channels_)
  102. << "Number of channels of mean file doesn't match input layer.";
  103. /* The format of the mean file is planar 32-bit float BGR or grayscale. */
  104. std::vector<cv::Mat> channels;
  105. float* data = mean_blob.mutable_cpu_data();
  106. for (int i = 0; i < num_channels_; ++i) {
  107. /* Extract an individual channel. */
  108. cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
  109. channels.push_back(channel);
  110. data += mean_blob.height() * mean_blob.width();
  111. }
  112. /* Merge the separate channels into a single image. */
  113. cv::Mat mean;
  114. cv::merge(channels, mean);
  115. /* Compute the global mean pixel value and create a mean image
  116. * filled with this value. */
  117. cv::Scalar channel_mean = cv::mean(mean);
  118. mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);
  119. }
  120. std::vector<float> Classifier::Predict(const cv::Mat& img) {
  121. Blob<float>* input_layer = net_->input_blobs()[0];
  122. input_layer->Reshape(1, num_channels_,
  123. input_geometry_.height, input_geometry_.width);
  124. /* Forward dimension change to all layers. */
  125. net_->Reshape();
  126. std::vector<cv::Mat> input_channels;
  127. WrapInputLayer(&input_channels);
  128. Preprocess(img, &input_channels);
  129. net_->ForwardPrefilled();
  130. /* Copy the output layer to a std::vector */
  131. Blob<float>* output_layer = net_->output_blobs()[0];
  132. const float* begin = output_layer->cpu_data();
  133. const float* end = begin + output_layer->channels();
  134. return std::vector<float>(begin, end);
  135. }
  136. /* Wrap the input layer of the network in separate cv::Mat objects
  137. * (one per channel). This way we save one memcpy operation and we
  138. * don't need to rely on cudaMemcpy2D. The last preprocessing
  139. * operation will write the separate channels directly to the input
  140. * layer. */
  141. void Classifier::WrapInputLayer(std::vector<cv::Mat>* input_channels) {
  142. Blob<float>* input_layer = net_->input_blobs()[0];
  143. int width = input_layer->width();
  144. int height = input_layer->height();
  145. float* input_data = input_layer->mutable_cpu_data();
  146. for (int i = 0; i < input_layer->channels(); ++i) {
  147. cv::Mat channel(height, width, CV_32FC1, input_data);
  148. input_channels->push_back(channel);
  149. input_data += width * height;
  150. }
  151. }
  152. void Classifier::Preprocess(const cv::Mat& img,
  153. std::vector<cv::Mat>* input_channels) {
  154. /* Convert the input image to the input image format of the network. */
  155. cv::Mat sample;
  156. if (img.channels() == 3 && num_channels_ == 1)
  157. cv::cvtColor(img, sample, CV_BGR2GRAY);
  158. else if (img.channels() == 4 && num_channels_ == 1)
  159. cv::cvtColor(img, sample, CV_BGRA2GRAY);
  160. else if (img.channels() == 4 && num_channels_ == 3)
  161. cv::cvtColor(img, sample, CV_BGRA2BGR);
  162. else if (img.channels() == 1 && num_channels_ == 3)
  163. cv::cvtColor(img, sample, CV_GRAY2BGR);
  164. else
  165. sample = img;
  166. cv::Mat sample_resized;
  167. if (sample.size() != input_geometry_)
  168. cv::resize(sample, sample_resized, input_geometry_);
  169. else
  170. sample_resized = sample;
  171. cv::Mat sample_float;
  172. if (num_channels_ == 3)
  173. sample_resized.convertTo(sample_float, CV_32FC3);
  174. else
  175. sample_resized.convertTo(sample_float, CV_32FC1);
  176. cv::Mat sample_normalized;
  177. cv::subtract(sample_float, mean_, sample_normalized);
  178. /* This operation will write the separate BGR planes directly to the
  179. * input layer of the network because it is wrapped by the cv::Mat
  180. * objects in input_channels. */
  181. cv::split(sample_normalized, *input_channels);
  182. CHECK(reinterpret_cast<float*>(input_channels->at(0).data)
  183. == net_->input_blobs()[0]->cpu_data())
  184. << "Input channels are not wrapping the input layer of the network.";
  185. }
  186. //获取路径path下的文件,并保存在files容器中
  187. void getFiles(string path, vector<string>& files)
  188. {
  189. //文件句柄
  190. long   hFile = 0;
  191. //文件信息
  192. struct _finddata_t fileinfo;
  193. string p;
  194. if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
  195. {
  196. do
  197. {
  198. if ((fileinfo.attrib &  _A_SUBDIR))
  199. {
  200. if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
  201. getFiles(p.assign(path).append("\\").append(fileinfo.name), files);
  202. }
  203. else
  204. {
  205. files.push_back(p.assign(path).append("\\").append(fileinfo.name));
  206. }
  207. } while (_findnext(hFile, &fileinfo) == 0);
  208. _findclose(hFile);
  209. }
  210. }
  211. int main(int argc, char** argv) {
  212. //caffe的准备工作
  213. #ifdef _MSC_VER
  214. #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
  215. #endif
  216. //::google::InitGoogleLogging(argv[0]);
  217. string model_file("../../model/deploy.prototxt");
  218. string trained_file("../../model/type.caffemodel");
  219. string mean_file("../../model/type_mean.binaryproto");
  220. string label_file("../../model/labels.txt");
  221. string picture_path("../../type");
  222. Classifier classifier(model_file, trained_file, mean_file, label_file);
  223. vector<string> files;
  224. getFiles(picture_path, files);
  225. for (int i = 0; i < files.size(); i++)
  226. {
  227. cv::Mat img = cv::imread(files[i], -1);
  228. cv::Mat img2;
  229. std::vector<Prediction> predictions = classifier.Classify(img);
  230. Prediction p = predictions[0];
  231. CvSize sz;
  232. sz.width = img.cols;
  233. sz.height = img.rows;
  234. float scal = 0;
  235. scal = sz.width > sz.height ? (300.0 / (float)sz.height) : (300.0 / (float)sz.width);
  236. sz.width *= scal;
  237. sz.height *= scal;
  238. resize(img, img2, sz, 0, 0, CV_INTER_LINEAR);
  239. IplImage* show = cvCreateImage(sz, IPL_DEPTH_8U, 3);
  240. string text = p.first;
  241. char buff[20];
  242. _gcvt(p.second, 4, buff);
  243. text = text + ":" + buff;
  244. /************************输出中文(用到Freetype库)****************************/
  245. /*CvxText mytext("../../STZHONGS.TTF");// 字体文件
  246. const char *msg = text.c_str();
  247. CvScalar size;
  248. size.val[0] = 26;
  249. size.val[1] = 0.5;
  250. size.val[2] = 0.1;
  251. size.val[3] = 0;
  252. mytext.setFont(NULL,&size, NULL, NULL);   // 设置字体大小
  253. mytext.putText(&IplImage(img2), msg, cvPoint(10, 30), cvScalar(0, 0, 255, NULL));
  254. //输出图像名
  255. text = files[i].substr(files[i].find_last_of("\\")+1);
  256. msg = text.c_str();
  257. mytext.putText(&IplImage(img2), msg, cvPoint(10, 55), cvScalar(0, 0, 255, NULL));
  258. cvCopy(&(IplImage)img2, show);*/
  259. /*******************************************************************************/
  260. /***************************输出英文标签*****************************************/
  261. cvCopy(&(IplImage)img2, show);
  262. CvFont font;
  263. cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 1.0, 1.0, 0, 2, 8);  //初始化字体
  264. cvPutText(show, text.c_str(), cvPoint(10, 30), &font, cvScalar(0, 0, 255, NULL));
  265. text = files[i].substr(files[i].find_last_of("\\")+1);
  266. cvPutText(show, text.c_str(), cvPoint(10, 55), &font, cvScalar(0, 0, 255, NULL));
  267. /**********************************************************************************/
  268. cvNamedWindow("结果展示");
  269. cvShowImage("结果展示", show);
  270. int c = cvWaitKey();
  271. cvDestroyWindow("结果展示");
  272. cvReleaseImage(&show);
  273. if (c == 27)
  274. {
  275. return 0;
  276. }
  277. }
  278. return 0;
  279. }

3.生成

设置好之后,右键caffelib,生成。

4.结果

左边是中文标签,右边是英文标签。

最后,可以删除那些不需要的文件或文件夹,如我的caffe-windows-master内只留下:

也可以下载我封装好的代码,可通过链接下载:http://download.csdn.net/detail/sinat_30071459/9568131  是一个txt文件,因为csdn上传限制,代码上传到了百度云,txt里面有百度云链接。下载解压后将Classification\CLassificationDLL\bin加入环境变量,然后加入你的模型文件即可。

Windows下用VS2013加载caffemodel做图像分类相关推荐

  1. windows下应用程序加载DLL动态链接库路径

    windows下应用程序加载动态链接库路径依次分别是: 举例D盘soft文件夹下存在了一个test.exe的执行文件,即d:\soft\test.exe,依赖test.dll动态链接库. ■程序的执行 ...

  2. windows下使用训练好的caffemodel做分类(2016-11-01)(车型分类)

    转自:http://blog.csdn.net/shakevincent/article/details/52995253 版权声明:本文为博主原创文章,未经博主允许不得转载. 随着深度学习的发展,越 ...

  3. Windows PE 第十章 加载配置信息

    加载配置信息 加载配置信息最初最用在Windows NT操作系统中,作为文件头部的延伸部分,后来被用作异常处理.加载配置信息表中存放了基于结构化异常处理(SEH)技术的各项异常句柄.当程序运行发生异常 ...

  4. 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线...

    重温.NET下Assembly的加载过程 最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后发现 ...

  5. 重温.NET下Assembly的加载过程

    最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后发现,并没能解决我的问题,有些点写的不是特别详 ...

  6. win7ie11调用java失败,win7纯净版系统下ie11无法加载java插件

    在win7纯净版系统中,我们会使用系统自带IE11浏览器来上网,最近有用户在使用IE11上网的时候无法加载java插件,导致网页无法全部显示,我们碰到这个问题应该怎么解决呢?下面给大家讲解一下win7 ...

  7. 百度地图:层级地图、行政边界、圆形覆盖物、自定义覆盖物、可视化数据显示、放大及缩小、下拉滚动加载数据等...

    写了一天,以下是我自己摸索出来的,暂时只做了两层地图,废话不多说,上图上代码 图片: 第一层地图 点击圆形覆盖物或者放大地图进入第二层地图,缩放会回到第一层 拖拽地图或者缩放地图会触发可视化数据 下拉 ...

  8. tensorflow中保存模型、加载模型做预测(不需要再定义网络结构)

    下面用一个线下回归模型来记载保存模型.加载模型做预测 参考文章: http://blog.csdn.net/thriving_fcl/article/details/71423039 训练一个线下回归 ...

  9. 怎么样给下拉框加载背景色

    选择自 PPLUNCLE 的 Blog 部分代码: ------aspx页面:  <tr>  <td><select id="job" name=&q ...

最新文章

  1. 10大类、142条数据源,中文NLP数据集线上搜索开放
  2. mac上投屏android_全平台Win/Mac全设备Android/iOS 免费无线投屏神器
  3. 用 Flutter 开发真的NX
  4. VS中Debug和Release版本的区别
  5. 【OpenCV 例程200篇】97. 反谐波平均滤波器
  6. 数据仓库之电商数仓-- 3.3、电商数据仓库系统(DWT层)
  7. java io 机器名_java IO最让初学者误解的取名方式
  8. hdu4410(Boomerang)(计算几何)
  9. 移植busybox构建最小根文件系统
  10. 怎么修照片多余的部分_眉毛不会画怎么办?眉笔眉粉染眉膏到底怎么选?看完就会了...
  11. 离线地图下载及地图瓦片制作
  12. h5 +css +js +jq 基础知识总结
  13. HONOR Magicbook 进不了系统
  14. java 中的todo_详解在TodoController中引用TodoRepository
  15. ios 七种手势详解
  16. Java进阶——Java中的字符串常量池
  17. I.MX6 AW-NB177NF wifi HAL
  18. 牛客算法周周练11 A.切题之路 签到题
  19. 华为AppEngine学习
  20. 分享IT业的创业心得

热门文章

  1. BOOST_SCOPE_EXIT_TPL宏相关的测试程序
  2. boost::mpl::not_equal_to相关的测试程序
  3. boost::mp11::mp_set_difference相关用法的测试程序
  4. Boost::context模块callcc的无限循环测试程序
  5. ITK:计算图像谱密度
  6. VTK:可视化之VisualizeImageData
  7. VTK:可视化之ExtrudePolyDataAlongLine
  8. VTK:PolyData之PointLocator
  9. C语言实现哈密尔顿hamiltonian算法(附完整源码)
  10. ++i 和 i++的实现