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(參數塊數)
剩下的是網絡結構。