結合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;

}






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM