C++中使用OPENCV对深度学习的特征图进行可视化

//需要先在运行目录下创建文件夹opencv_layers
#include <iostream>
#include <unistd.h>
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/dnn.hpp>
#include <opencv4/opencv2/dnn/dnn.hpp>

using namespace std;

/*
equal list

opencv_conv*relu = pycaffe_conv*

*/

int main(int argc, char *argv[])
{
    //// SHOULD BE 4.*.*
    cerr<<"WORKING IN OPENCV_VERSION "<<CV_VERSION<<'\n';
    cv::Mat src = cv::imread("src.jpg");

    string cfg     ="deploy.prototxt";
    string weights ="net_iter_25000.caffemodel";
    cv::dnn::Net net = cv::dnn::readNetFromCaffe(cfg,weights);

    if(net.empty()){
        cerr<<"loaded net failed.\n";
        return -1;
    }

    cv::Mat inputBlob = cv::dnn::blobFromImage(src, 1/255.F, cv::Size(300, 300), cv::Scalar(), false, false);
    net.setInput(inputBlob,"data");

    vector<cv::String> outputname=net.getLayerNames();
    outputname.insert(outputname.begin(),"data");
    cv::dnn::MatShape netInputSize = {1,3,300,300};
    vector<cv::dnn::MatShape> netlastSize;
    vector<vector<cv::dnn::MatShape> >layerSizes;
    for(size_t i=0;i<outputname.size();++i){
        vector<cv::dnn::MatShape>inputLayerSize;
        vector<cv::dnn::MatShape>outputLayerSize;
        net.getLayerShapes(netInputSize,i,inputLayerSize,outputLayerSize);
        cerr<<"layer <<"<<outputname[i]<<">> size [\n";
        for(size_t j=0;j<inputLayerSize.size();++j){
            cerr<<"\t["<<inputLayerSize[j][0];for(size_t k=1;k<inputLayerSize[j].size();++k)cerr<<" x "<<inputLayerSize[j][k];cerr<<"]\n";
        }
        cerr<<"\tto\n";
        for(size_t j=0;j<outputLayerSize.size();++j){
            cerr<<"\t["<<outputLayerSize[j][0];for(size_t k=1;k<outputLayerSize[j].size();++k)cerr<<" x "<<outputLayerSize[j][k];cerr<<"]\n";
        }
        cerr<<"]\n";
        layerSizes.push_back(outputLayerSize);
        netlastSize=inputLayerSize;
    }


    vector<vector<cv::Mat> > outputBlob;
    try{
        cerr<<"\nNet forward ";
        net.forward(outputBlob, outputname);
        cerr<<"done\n\n";
    }catch(exception e){
        cerr << e.what() << '\n';
    }

    string selectLayer="conv4";

    for(size_t i=0;i<outputname.size();++i){
        
        for(size_t j=0;j<outputBlob[i].size();++j){
            try{

                cv::Mat blob;
                cv::normalize(outputBlob[i][j], blob, 255, 0, cv::NORM_MINMAX);
                

                cerr<<"blob dim = "<<blob.size.dims()<<" with type "<<blob.type()<<'\n';
                //b * c * w * h
                //b * w * h
                //b * w
                cerr<<"blob shape ["<<blob.size.p[0];for(size_t k=1;k<blob.size.dims();++k)cerr<<" x "<<blob.size.p[k];cerr<<"]\n";
                cerr<<"real shape ["<<layerSizes[i][j][0];for(size_t k=1;k<layerSizes[i][j].size();++k)cerr<<" x "<<layerSizes[i][j][k];cerr<<"]\n";

                cv::Mat saveimg;
                float* data=(float*)blob.data;
                string savepath;
                int s[6]={0};

                switch(blob.size.dims()){
                case 2:
                    saveimg.create(layerSizes[i][j][1],1,CV_8UC1);
                    for(size_t pi=0; pi<layerSizes[i][j][1]; ++pi){
                        saveimg.data[pi]=data[pi];
                    }
                    savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
                    cv::imwrite(savepath,saveimg);
                    saveimg.release();
                    break;
                case 3:
                    s[1]=layerSizes[i][j][1];
                    s[0]=layerSizes[i][j][2];
                    saveimg.create(layerSizes[i][j][1],layerSizes[i][j][2],CV_8UC1);
                    for(size_t pi=0; pi<s[1]*s[0]; ++pi){
                        saveimg.data[pi]=(uchar)data[pi];
                    }
                    savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
                    cv::imwrite(savepath,saveimg);
                    saveimg.release();
                    break;
                case 4:
                    s[1]=layerSizes[i][j][2];
                    s[0]=layerSizes[i][j][3];
                    s[2]=s[1]*s[0];
                    s[3]=ceil(sqrt(layerSizes[i][j][1]));
                    s[4]=0;
                    saveimg=cv::Mat::zeros((s[1]+2)*s[3],(s[0]+2)*s[3],CV_8UC1);
                    fprintf(stderr,"saveimg <%d,%d> for %d\n",saveimg.rows,saveimg.cols,layerSizes[i][j][1]);
                    for(size_t wy=0; wy<s[3]; ++wy){
                        for(size_t wx=0; wx<s[3]; ++wx){
                            if(s[4]>=layerSizes[i][j][1])break;
                            s[5]=0;
                            for(size_t py=0; py<s[1]; ++py){
                                for(size_t px=0; px<s[0]; ++px){
                                    saveimg.data[(wy*(s[1]+2)+py)*s[3]*(s[0]+2)+wx*(s[0]+2)+px]=(uchar)data[s[4]*s[2]+s[5]];
                                    ++s[5];
                                }
                            }
                            ++s[4];
                        }
                    }

                    savepath = "opencv_layers/layer_"+strip(outputname[i],"/")+".jpg";
                    cv::imwrite(savepath,saveimg);
                    saveimg.release();
                    break;
                default:
                    cerr<<" exordinary dim\n";
                    break;
                }
                cerr<<"save to "<<savepath<<'\n';

                blob.release();
            }catch(exception e){
                cerr<<" escape beacuse "<<e.what()<<'\n';
            }
        }
    }

    fprintf(stderr, "float %d, double %d\n",sizeof(float),sizeof(double));
    //blob <CV_32FC1,5> float
    fprintf(stderr, "type list : <CV_8UC1,%d> <CV_8UC3,%d> <CV_16FC1,%d> <CV_16FC3,%d> <CV_16SC1,%d> <CV_16SC3,%d> <CV_32FC1,%d> <CV_32SC1,%d> ",
            CV_8UC1,CV_8UC3,CV_16FC1,CV_16FC3,CV_16SC1,CV_16SC3,CV_32FC1,CV_32SC1);
    return 0;
}
 

 

posted @ 2019-05-05 17:22  aimhabo  阅读(2119)  评论(0编辑  收藏  举报