//需要先在运行目录下创建文件夹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<<' '; 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. "; 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 [ "; for(size_t j=0;j<inputLayerSize.size();++j){ cerr<<" ["<<inputLayerSize[j][0];for(size_t k=1;k<inputLayerSize[j].size();++k)cerr<<" x "<<inputLayerSize[j][k];cerr<<"] "; } cerr<<" to "; for(size_t j=0;j<outputLayerSize.size();++j){ cerr<<" ["<<outputLayerSize[j][0];for(size_t k=1;k<outputLayerSize[j].size();++k)cerr<<" x "<<outputLayerSize[j][k];cerr<<"] "; } cerr<<"] "; layerSizes.push_back(outputLayerSize); netlastSize=inputLayerSize; } vector<vector<cv::Mat> > outputBlob; try{ cerr<<" Net forward "; net.forward(outputBlob, outputname); cerr<<"done "; }catch(exception e){ cerr << e.what() << ' '; } 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()<<' '; //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<<"] "; 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<<"] "; 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 ",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 "; break; } cerr<<"save to "<<savepath<<' '; blob.release(); }catch(exception e){ cerr<<" escape beacuse "<<e.what()<<' '; } } } fprintf(stderr, "float %d, double %d ",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; }