windows下使用训练好的caffemodel做分类(2016-11-01)(车型分类)
转自:http://blog.csdn.net/shakevincent/article/details/52995253
版权声明:本文为博主原创文章,未经博主允许不得转载。
随着深度学习的发展,越来越多的人开始进入这个行业,希望可以有所进展,但是各行业的大牛们,速度超神,deep哈希、deep稀疏、deep做分类、识别、跟踪、等等。很多人也开始训练自己的数据集或者下载别人训练好的model。训练好的caffemodel怎么使用对于刚入门的深度学习人来说是比较困难的,或者怎么用模型去验证自己的数据集等等
下面就从以下方向来说明怎么使用训练好model来预测自己的图片
1:编译caffe for windows
微软提供Windows工具包(caffe-master):https://github.com/Microsoft/caffe
此版严格只支持VS2013。此版本无需配置任何第三方环境哦,因为在项目属性里面都已经包含进去了,非常方便。如果出现了一些文件打不开或者其它问题,第一可能是VS自身问题,第二可能你配置过其它caffe,修改过环境变量,导致找不到头文件之类的。
caffe for windows的编译:
可以参考我的博客:
http://blog.csdn.net/shakevincent/article/details/51694686
http://m.blog.csdn.net/article/details?id=51355143
http://m.blog.csdn.net/article/details?id=51549105
编译好caffe-windows后删除其他不需要的工程,仅保留caffelib 和classfication工程。
打开classfication工程里面的classfication.cpp函数修改:
#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 <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>#include <iostream>
#include <string>
#include <sstream>
#include "io.h"#include "stdio.h"
#include "stdlib.h"
#include "time.h" #ifdef USE_OPENCV
using namespace caffe; // NOLINT(build/namespaces)
using std::string;/* 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);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:shared_ptr<Net<float> > net_;cv::Size input_geometry_;int num_channels_;cv::Mat mean_;std::vector<string> labels_;
};Classifier::Classifier(const string& model_file,const string& trained_file,const string& mean_file,const string& label_file) {
#ifdef CPU_ONLYCaffe::set_mode(Caffe::CPU);
#elseCaffe::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);elsesample = img;cv::Mat sample_resized;if (sample.size() != input_geometry_)cv::resize(sample, sample_resized, input_geometry_);elsesample_resized = sample;cv::Mat sample_float;if (num_channels_ == 3)sample_resized.convertTo(sample_float, CV_32FC3);elsesample_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.";
}
//获取路径path下的文件,并保存在files容器中
void getFiles(string path, vector<string>& files)
{//文件句柄 long hFile = 0;//文件信息 struct _finddata_t fileinfo;string p;if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1){do{if ((fileinfo.attrib & _A_SUBDIR)){if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)getFiles(p.assign(path).append("\\").append(fileinfo.name), files);}else{files.push_back(p.assign(path).append("\\").append(fileinfo.name));}} while (_findnext(hFile, &fileinfo) == 0);_findclose(hFile);}
}int main(int argc, char** argv) {string model_file("../model/deploy.prototxt");string trained_file("../model/type.caffemodel");string mean_file("../model/type_mean.binaryproto");string label_file("../model/labels.txt");string picture_path("../model/type");Classifier classifier(model_file, trained_file, mean_file, label_file);vector<string> files;getFiles(picture_path, files);for (int i = 0; i < files.size(); i++){clock_t start, finish;double duration;start = clock();cv::Mat img = cv::imread(files[i], -1);cv::Mat img2;std::vector<Prediction> predictions = classifier.Classify(img);//Prediction p = predictions[i];IplImage* show;CvSize sz;sz.width = img.cols;sz.height = img.rows;float scal = 0;scal = sz.width > sz.height ? (300.0 / (float)sz.height) : (300.0 / (float)sz.width);sz.width *= scal;sz.height *= scal;resize(img, img2, sz, 0, 0, CV_INTER_LINEAR);show = cvCreateImage(sz, IPL_DEPTH_8U, 3);cvCopy(&(IplImage)img2, show);CvFont font;cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 1, 8); //初始化字体 //cvPutText(show, text.c_str(), cvPoint(10, 30), &font, cvScalar(0, 0, 255, NULL));string name_text;name_text = files[i].substr(files[i].find_last_of("\\") + 1);name_text = "Test picture ID::"+ name_text;cvPutText(show, name_text.c_str(), cvPoint(10, 130), &font, cvScalar(0, 0, 255, NULL));for (size_t i = 0; i < predictions.size(); ++i){Prediction p = predictions[i];std::cout << std::fixed << std::setprecision(4) << p.second << " - \""<< p.first << "\"" << std::endl;string text = p.first;char buff[20];_gcvt(p.second, 4, buff);text = text + ":" + buff;/***************************输出英文标签*****************************************///CvFont font;//cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 1, 8); //初始化字体 //cvPutText(show, text.c_str(), cvPoint(10, 30), &font, cvScalar(0, 0, 255, NULL));//string name_text;cvPutText(show, text.c_str(), cvPoint(10, 30 + i * 20), &font, cvScalar(0, 0, 255, NULL));/**********************************************************************************/cvNamedWindow("结果");cvShowImage("结果", show);cvWaitKey(1);}finish = clock();duration = (double)(finish - start) / CLOCKS_PER_SEC;printf("Time to do is ::");printf("%f seconds\n", duration);int c = cvWaitKey();cvDestroyWindow("结果");cvReleaseImage(&show);std::cout << "///" << std::endl;if (c == 27){return 0;}}return 0;
}
#else
int main(int argc, char** argv) {LOG(FATAL) << "This example requires OpenCV; compile with USE_OPENCV.";
}
#endif // USE_OPENCV
- 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
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 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
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
1:下载model:这里使用训练好的车辆识别的model
2:修改一下文件:
string model_file("../model/deploy.prototxt");string trained_file("../model/type.caffemodel");string mean_file("../model/type_mean.binaryproto");string label_file("../model/labels.txt");string picture_path("../model/type");//测试图片的路径
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
简单修改后就可以使用了。
model下载地址:链接:http://pan.baidu.com/s/1hs3CF9y 密码:j7m4
windows下使用训练好的caffemodel做分类(2016-11-01)(车型分类)相关推荐
- Windows下用VS2013加载caffemodel做图像分类
本文假设你已经安装CUDA,CUDA版本是7.5. 1.编译caffe的Windows版本 happynear的博客已经介绍了如何在windows下编译caffe,这里把我自己编译的过程记录下来,也算 ...
- Windows下Tesseract训练音符识别
Windows下Tesseract训练音符识别 背景 开局一张图:现在有这么一个需求,要将数字简谱中的数字带点的内容识别出来做进一步的处理,比如 6 1 6 641 533 . . ... 识别成 F ...
- windows下Icnet训练自己的数据集
一.数据集标注:Labelme 安装后labelme后,在C:\Users\xxx\Anaconda3\Lib\site-packages\labelme\utils下修改_io.py def lbl ...
- mnist数据集在caffe(windows)上的训练与测试及对自己手写数字的分类
以下出自http://www.cnblogs.com/yixuan-xu/p/5858595.html 我按照大神的运算步骤完全正确,只是为了加深理解,自己又重新写了一遍,详情请看上述大神博客. 对m ...
- 【1】windows下IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- 在windows下架设openssh实现资源共享
本来来说.这种用途是十分罕见的.window之间的共享自身有自己的协议.linux与windows共享也不会哪个傻B想到要在windows下来进行安装.怎么说也是装在linux方便啦.不过确实这种傻B ...
- 【音视频】RTMP:windows下搭建rtmp服务器(未完结...)
0.RTMP服务器简介 0.1 Nginx-RTMP 使用Nginx和Nginx的RTMP模块(nginx-rtmp-module)搭建RTMP流媒体服务器. Nginx 是一款轻量级的 Web 服务 ...
- Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)
前言 之前有用OpenCv的SUFT特征提取和SVM.BOW做过按图像里的内容进行分类的相关项目,耗时长,准确率又不是很高,各种优化之后准确率也只有百分七十到八十,所以一直想用caffe试试. 一.系 ...
- 在windows下运行Felzenszwalb的Deformable Part Model(DPM)源码voc-release3.1来训练自己的模型
我的环境 DPM源码版本:voc-release3.1 VOC开发包版本:VOC2007_devkit_08-Jun 使用的训练数据集:VOC2007 ...
最新文章
- HDU2083排序题
- [转]php与memcached服务器交互的分布式实现源码分析[memcache版]
- 数据库三范式的理解(引用其他网友)
- what can be learned from a friend?
- 移动开发新利器 | 一文深入了解 Flutter 界面开发
- App设计灵感之十二组精美的机票预订App设计案例
- 推动边缘计算的七项核心技术
- 300 秒搞定第一超算 1 万年的计算量,量子霸权时代已来? | CSDN 博文精选
- 水逆的美团滴滴与头条
- 【算法学习】Fast burst images denoising
- Web常见前端面试题及答案
- JAVA中的getBytes()方法(史上最能明白的总结)
- STM32L0外接32768HZ晶振应该接多大的负载电容才合适
- 【FPGA教程案例89】编译码2——使用vivado核实现RS信道编译码
- matlab和robotstudio,一种从Robotstudio环境中导出机器人模型并在MATLAB下使其可视化的研究记录...
- 七大江河水系--长江(二)
- Nginx 配置长连接
- C++下的OpenCV中Mat类型存储的图像格式
- [博弈论] Nim游戏及SG函数(经典+台阶+集合+拆分)
- Unity Shader 实现简单的宝石渲染
热门文章
- 电脑音频喇叭图标有“X“,驱动也没掉,问题解决
- 工信部信软司副司长王建伟-《工业互联网平台发展与展望》
- RecyclerView中获取item在屏幕中的绝对坐标
- TOPIK 韩语考试历届考题下载
- 新人找客户的方法有哪些?专业渠道总结,收藏!
- java闰年满五换行_【计算机二级Java语言】卷013
- CPU的架构:x86、arm、mips、龙芯等
- 2021年中国核受体γ市场趋势报告、技术动态创新及2027年市场预测
- 找回在foxmail中登录过的帐号密码
- 斯坦福大学吴恩达机器学习教程中文笔记——week1——引言,单变量线性回归,线性代数回顾