• 结合OpenCV可视化Caffe神经网络中的特征层


    Caffe中,卷积的作用是提取抽象特征,很多层卷积逐渐获得一幅图像的抽象特征,为后面分类打下基础。而究竟这些抽象特征是什么,是形状?是纹理?是投影?还是颜色?还是都有,需要直观的去看了。可视化诸层很有必要。Python的源码在caffe官网上有,不再赘述。C++的代码,可以借助OpenCV中的dnn模块获取。本程序是基于OpenCV的dnn模块中的例子改编的。

    OpenCV dnn Example 点击

    OpenCV3.1中的小点心

    • 关于getPlane的用法:
    
    Mat cv::dnn::Blob::getPlane ( int n,
    
    int cn
    
    )
    
    Returns slice of first two dimensions. 
    The behaviour is similar to the following numpy code: blob[n, cn, …]
    
    
    • 代码如下:
    Mat img40(Mat& srcimg)
    {
        Mat img;
        resize(srcimg,img,Size(32,32));
         	    	//img.copyTo(binary_img);
    
    		Mat in_large=Mat::zeros(Size(40,40),img.type());//建立黑板
    
    
    		float x = in_large.cols / 2 - img.cols / 2;//两个图像的中心点差x坐标
    		float y = in_large.rows / 2 - img.rows / 2;//两个图像的中心点差y坐标
    //将图像A(20×20)按照上下左右各空出x或y的像素宽,复制到B(28×28)。
    		copyMakeBorder(img, in_large, y, y, x, x, BORDER_CONSTANT, Scalar::all(0));
    
    		resize(in_large, in_large, Size(40, 40));//由于有个bug,重新标准化
    
            return in_large;
    }
    
    //批量处理函数
    void createDocList(std::vector<std::string> &doc_list){
        int return_code;
        DIR *dir;
        struct dirent entry;
        struct dirent *res;
        string real_dir = "./img";//搜索的目录
        if ((dir = opendir(real_dir.c_str())) != NULL) {//打开目录
            for (return_code = readdir_r(dir, &entry, &res);res != NULL && return_code == 0;return_code = readdir_r(dir, &entry, &res)) {
                if (entry.d_type != DT_DIR) {//存放到列表中
    
                    doc_list.push_back(string(entry.d_name));
    
                }
            }
            closedir(dir);//关闭目录
        }
    }
    
    int main(int argc, char **argv)
    
    {
    
        String modelTxt = "lenet_hanzi_yao_s.prototxt";
    
        String modelBin = "lenet_iter_100000.caffemodel";
    
        
    
        // String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
    
        //String imageFile = (argc > 1) ? argv[1] : "/hanzi/h950.jpg";
    
        
    
        string file_path = "./img/";
    
        string search_path = file_path + "*.jpg";
    
        vector<string> file_list;
    
        createDocList(file_list);
    
        //sort(file_list.begin(),file_list.end(),Num);
    
        cout<<"chengxu"<<file_list.size()<<endl;
    
        if (file_list.size()==0)
    
        cout << "open file error!" << endl;
    
        
    
        Ptr<dnn::Importer> importer;
    
        try                                     //Try to import Caffe GoogleNet model
    
        {
    
        importer = dnn::createCaffeImporter(modelTxt, modelBin);
    
        }
    
        catch (const cv::Exception &err)        //Importer can throw errors, we will catch them
    
        {
    
        std::cerr << err.msg << std::endl;
    
        }
    
        if (!importer)
    
        {
    
        std::cerr << "Can't load network by using the following files: " << std::endl;
    
        std::cerr << "prototxt:   " << modelTxt << std::endl;
    
        std::cerr << "caffemodel: " << modelBin << std::endl;
    
        std::cerr << "bvlc_googlenet.caffemodel can be downloaded here:" << std::endl;
    
        std::cerr << "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel" << std::endl;
    
        exit(-1);
    
        }
    
        dnn::Net net;
    
        importer->populateNet(net);
    
        importer.release();                     //We don't need importer anymore
    
        
    
        for (int i = 0; i < file_list.size(); i++)
    
        {
    
        string image_path = file_path + file_list[i];
    
        
    
        Mat srcimg = imread(image_path,0);
    
        Mat img=img40(srcimg);//将图像转为40×40大小
    
        if (img.empty())
    
        {
    
            std::cerr << "Can't read image from the file: " << image_path << std::endl;
    
            exit(-1);
    
        }
    
        dnn::Blob inputBlob = dnn::Blob(img);   //Convert Mat to dnn::Blob image batch
    
        net.setBlob(".data", inputBlob);        //set the network input
    
        net.forward();                          //compute output
    
        dnn::Blob prob = net.getBlob("conv1"); //获取conv1层的Blob
    
        stringstream ss;
    
        
    
        stringstream ss;
    
        string s;
    
        
    
        for(int a=0;a<1;a++)
    
        {
    
            for(int j=0;j<20;j++)
    
            {
    
                ss<<i<<"["<<a<<","<<j<<"]"<<".jpg";
    
                ss>>s;
    
                Mat featureimg=prob.getPlane(a,j);//conv1层Blob中有20个抽象特征图层,可以全部输出。其中,a是指第几张图片,j是第几个特征层。
    
                imwrite(s,featureimg);
    
                ss.clear();
    
                s.clear();
    
            }
    
        
    
        }
    
        
    
        	}
    
            return 0;
    
    }
    
    
    
    
    
    
  • 相关阅读:
    Orchard源码分析(4.3):Orchard.Events.EventsModule类(Event Bus)
    Orchard源码分析(4.2):Orchard.Logging.LoggingModule类
    Orchard源码分析(4.1):Orchard.Environment.CollectionOrderModule类
    Orchard源码分析(4):Orchard.Environment.OrchardStarter类
    Orchard源码分析(3):Orchard.WarmupStarter程序集
    Orchard源码分析(2):Orchard.Web.MvcApplication类(Global)
    MSSQL
    MSSQL
    C#、WinForm、ASP.NET
    C#、WinForm、ASP.NET
  • 原文地址:https://www.cnblogs.com/anmengcv/p/5641482.html
Copyright © 2020-2023  润新知