自己编写程序,将手写图片送入训练得到的lenet模型,评估识别结果。
code:https://github.com/lhnows/caffeProjects
如果自己的caffe是用CMakeLists编译安装的,这样的话,可以运行如下的CMakeLists来编译自己的调用了caffe库的程序

CMakeLists.txt


cmake_minimum_required (VERSION 2.8)

PROJECT (mnistTest)


# Requires OpenCV v2.4.1 or later  
FIND_PACKAGE( OpenCV REQUIRED )  
IF (${OpenCV_VERSION} VERSION_LESS 2.4.1)  
    MESSAGE(FATAL_ERROR "OpenCV version is not compatible : ${OpenCV_VERSION}. requires atleast OpenCV v2.4.1")  
ENDIF() 


find_package(Caffe)  
include_directories(${Caffe_INCLUDE_DIRS})  
add_definitions(${Caffe_DEFINITIONS})   

add_executable(${PROJECT_NAME} mnistTest.cpp)
include_directories ( /Users/liuhao/devlibs/deeplearning/caffe/install/include
    /usr/local/include
    /usr/local/cuda/include )

target_link_libraries(${PROJECT_NAME} ${Caffe_LIBRARIES}
                        ${OpenCV_LIBS}  )

mnistTest.cpp


#define USE_OPENCV 1
#define CPU_ONLY 1
//貌似caffe有3种矩阵计算加速方式 mkl  accelerate blas,本人Mac编译的可能是下面这种(其他会报错找不到头文件)
//#define USE_ACCELERATE

#include <iostream>
#include <string>


#include <caffe/caffe.hpp>
#include <vector>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "head.h"

#include <algorithm>
#include <iosfwd>
#include <memory>
#include <utility>
#include <vector>
using namespace caffe;
using namespace cv;


cv::Point previousPoint(-1, -1), nowPoint(-1, -1);
Mat srcimage=Mat::zeros(280,280,CV_8UC1);
Mat srcimageori = Mat::zeros(280, 280, CV_8UC1);

class Classifier {
public:
    Classifier(const string& model_file,
        const string& trained_file);

    int Classify(const cv::Mat& img);

private:

    std::vector<int> 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_;
};

Classifier::Classifier(const string& model_file,
    const string& trained_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());

}

/* Return the top N predictions. */
int Classifier::Classify(const cv::Mat& img) {
    std::vector<int> output = Predict(img);
    std::vector<int>::iterator iter=find(output.begin(), output.end(), 1);
    int prediction = distance(output.begin(), iter);
    return prediction<10 ? prediction:0;
}
std::vector<int> 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<int>(begin, end);
}

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::split(sample_float, *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.";
}


static void on_Mouse(int event, int x, int y, int flags, void*)
{



    if (event == EVENT_LBUTTONUP || !(flags&EVENT_FLAG_LBUTTON))
    {
        previousPoint = cv::Point(-1,-1);
    }
    else
        if (event == EVENT_LBUTTONDOWN)
        {
            previousPoint = cv::Point(x, y);
        }
        else if (event == EVENT_MOUSEMOVE || (flags&EVENT_FLAG_LBUTTON))
        {
            cv::Point pt(x, y);
            if (previousPoint.x<0)
            {
                previousPoint = pt;
            }
            line(srcimage, previousPoint, pt, Scalar(255), 16, 8, 0);
            previousPoint = pt;
            imshow("result", srcimage);
        }

}


int main(int argc, char** argv)
{

    ::google::InitGoogleLogging(argv[0]);

#ifdef CPU_ONLY
    Caffe::set_mode(Caffe::CPU);
#else
    Caffe::set_mode(Caffe::GPU);
#endif

    string model_file = "lenet.prototxt";
    string trained_file = "lenet_iter_10000.caffemodel";
    Classifier classifier(model_file, trained_file);

    std::cout << "------directed by watersink------" << std::endl;
    std::cout << "------------enter:退出-----------" << std::endl;
    std::cout << "--------------1:还原-------------" << std::endl;
    std::cout << "-------------2:写数字------------" << std::endl;
    std::cout << "-----lhnows@qq.com-----" << std::endl;


    imshow("result", srcimage);
    setMouseCallback("result", on_Mouse, 0);
    while (1)
    {
        char c = (char)waitKey();
        if (c == 27)
            break;
        if (c=='1')
        {
            srcimageori.copyTo(srcimage);
            imshow("result", srcimage);
        }
        if (c == '2')
        {
            cv::Mat img;
            cv::resize(srcimage, img, cv::Size(28, 28));
            CHECK(!img.empty()) << "Unable to decode image " << std::endl;
            int  prediction = classifier.Classify(img);
            std::cout << "prediction:" << prediction << std::endl;
            imshow("result", srcimage);
        }
    }


    waitKey();
    return 0;

}

head.h

#include <caffe/common.hpp>
#include <caffe/layer.hpp>
#include <caffe/layer_factory.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/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(SoftmaxLayer);
    //REGISTER_LAYER_CLASS(Softmax);

}

cmake.. & make

 $ cmake ..
-- The C compiler identification is AppleClang 8.1.0.8020042
-- The CXX compiler identification is AppleClang 8.1.0.8020042
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version "3.2.0") 
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/liuhao/projects/caffeProjects/mnistTest/build


 $ make
Scanning dependencies of target mnistTest
[ 50%] Building CXX object CMakeFiles/mnistTest.dir/mnistTest.cpp.o
[100%] Linking CXX executable mnistTest
[100%] Built target mnistTest

输入./mnistTests 执行
这里写图片描述

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐