1.opencv
要做图像识别首先编译opencv2.4。官网下载opencv2.4
1 unzip opencv-3.2.0.zip
2 cd ~/opencv-3.2.0
3.编译opencv
cd ~/opencv-3.2.0
mkdir build
cd build
cmake …
make -j8
如果出现这个错误:
CMakeFiles/Makefile2:890: recipe for target 'modules/core/CMakeFiles/opencv_core.dir/all' failed
make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2
2.ncnn的编译
git clone https://github.com/Tencent/ncnn
cd ncnn
mkdir build && cd build
cmake ..
make -j
make install
3.模型的转化
下载的alexnet模型要先转化成新版的caffemodel,随后转化成.bin和.param文件
https://github.com/Tencent/ncnn/wiki/ncnn-组件使用指北-alexnet
如果你想量化这个模型,可以参考
https://github.com/BUG1989/caffe-int8-convert-tools
最后也是生成.bin和.param,生成的bin文件大约是源文件的1/4。
4.使用模型进行测试
需要自己新建一个目录,编写.cpp文件,然后写一个CMakeLists.txt进行编译。
CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.5)
find_package(OpenCV REQUIRED core highgui imgproc)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
include_directories(/home/zyr/quantize/ncnn/build/install/include)
link_directories(/home/zyr/quantize/ncnn/build/install/lib)
FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
add_executable(classify classify.cpp)
target_link_libraries(classify ncnn ${OpenCV_LIBS})
classify.cpp例子:
https://github.com/Tencent/ncnn/wiki/ncnn-组件使用指北-alexnet
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "net.h"
using namespace std;
int main(){
string img_path = "000002.jpg";
cv::Mat img = cv::imread(img_path, CV_LOAD_IMAGE_COLOR);
cv::Mat img2;
int input_width = 227;
int input_height = 227;
// resize图片大小 resize到alexnet的输入尺寸
cv::resize(img, img2, cv::Size(input_width, input_height));
// 加载转换并且量化后的alexnet网络
ncnn::Net net;
net.load_param("alexnet.param");
net.load_model("alexnet.bin");
// 把opencv的mat转换成ncnn的mat
ncnn::Mat input = ncnn::Mat::from_pixels(img2.data, ncnn::Mat::PIXEL_BGR, img2.cols, img2.rows);
// ncnn前向计算
ncnn::Extractor extractor = net.create_extractor();
extractor.input("data", input);
ncnn::Mat output;
extractor.extract("prob", output);
// 输出预测结果
ncnn::Mat out_flatterned = output.reshape(output.w * output.h * output.c);
std::vector<float> scores;
scores.resize(out_flatterned.w);
for (int j=0; j<out_flatterned.w; j++)
{
scores[j] = out_flatterned[j];
}
cout<<"done"<<endl;
return 0;
}
c++在linux下的编译:
cmake .
make
./classify
https://www.cnblogs.com/lidabo/p/7359422.html
http://www.cnblogs.com/dilex/p/9315308.html
5.param文件
Alexnet.param是这样的:
7767517
24 24
Input data 0 1 data 0=227 1=227 2=3
Convolution conv1 1 1 data conv1 0=96 1=11 2=1 3=4 4=0 5=1 6=34848 8=2
ReLU relu1 1 1 conv1 conv1_relu1
LRN norm1 1 1 conv1_relu1 norm1 0=0 1=5 2=0.000100 3=0.750000
Pooling pool1 1 1 norm1 pool1 0=0 1=3 2=2 3=0 4=0
ConvolutionDepthWise conv2 1 1 pool1 conv2 0=256 1=5 2=1 3=1 4=2 5=1 6=307200 7=2 8=2
ReLU relu2 1 1 conv2 conv2_relu2
LRN norm2 1 1 conv2_relu2 norm2 0=0 1=5 2=0.000100 3=0.750000
Pooling pool2 1 1 norm2 pool2 0=0 1=3 2=2 3=0 4=0
Convolution conv3 1 1 pool2 conv3 0=384 1=3 2=1 3=1 4=1 5=1 6=884736 8=2
ReLU relu3 1 1 conv3 conv3_relu3
ConvolutionDepthWise conv4 1 1 conv3_relu3 conv4 0=384 1=3 2=1 3=1 4=1 5=1 6=663552 7=2 8=2
ReLU relu4 1 1 conv4 conv4_relu4
ConvolutionDepthWise conv5 1 1 conv4_relu4 conv5 0=256 1=3 2=1 3=1 4=1 5=1 6=442368 7=2 8=2
ReLU relu5 1 1 conv5 conv5_relu5
Pooling pool5 1 1 conv5_relu5 pool5 0=0 1=3 2=2 3=0 4=0
InnerProduct fc6 1 1 pool5 fc6 0=4096 1=1 2=37748736
ReLU relu6 1 1 fc6 fc6_relu6
Dropout drop6 1 1 fc6_relu6 fc6_drop6
InnerProduct fc7 1 1 fc6_drop6 fc7 0=4096 1=1 2=16777216
ReLU relu7 1 1 fc7 fc7_relu7
Dropout drop7 1 1 fc7_relu7 fc7_drop7
InnerProduct fc8 1 1 fc7_drop7 fc8 0=1000 1=1 2=4096000
Softmax prob 1 1 fc8 prob 0=0 1=1
其中第一行的7767517是ncnn magic numger(幻数),
第二行的24 24。24为layer number(网络层数),24为blob number(参数块数)
剩下的是网络结构。