tensorflow C++ inference并行图像分割,cv::dnn不能并行?


前期参考:https://blog.csdn.net/wd1603926823/article/details/120781940 这里有关于tensorflow C++ inference with MKL/TBB的相关资料。

模型是Mask RCNN通过对输入图像加强边缘来达到图像分割的目的,于是我参考链接中的写法将模型换成model.pb后,报错如下:

Data loss: Can't parse model.pb as binary proto
terminate called after throwing an instance of 'std::runtime_error'
  what():  ERROR: Loading model failed...

解决办法:原来之前是使用的tensorflow::MetaGraphDef 读模型,然后后期通过.graph_def()转化成GraphDef。这个模型不再需要这样,而是直接用GraphDef去读model.pb而且后期不用再转化。

在预测结束后,以前是按下列这样拿到2维概率矩阵:
auto tmap = output.tensor<float, 2>(); 
改成下面这样拿到3维矩阵:
auto tmap = output.tensor<float, 3>(); 

原python下:

 python下出来的这个output是[rows,cols,1]的数组,所以只需取前2维数据即可得到分割后的结果图即加强边缘图如下所示:

类似这样,原图是粘连在一起的灰度图,经过模型分割后是这样。

C++下:

#include "linkuang.h"
using namespace std;
using namespace cv;
/*initialize CNN model in front of the system begin
 * input arg:imgsize-----------size of standard input image in tensorflow model
 *           wastethresh_prob--the second time judge the waste.
 *                             If the CNN inference prob for waste < wastethresh_prob,
 *                             we consider it as ore,not waste;
 * */
/*CNN的初始化部分:在系统初始化时调用一次即可。
 * 输入:imgsize-----------CNN模型要求的图像大小,不能太大(<=100)。建议:32、48、64
 *      lesswaste_prob----对废石的二次判断阈值(0.0,0.5~1)。如果CNN结果判为废石,且概率<=lesswaste_prob,
 *                        那么我们认为这不是真正的废石,其实是矿石。
 *                        lesswaste_prob==0.0,即表示不做阈值判断,完全相信CNN废石的结果;
 *                        lesswaste_prob越大,则抛废率越小;
 *      morewaste_prob----对矿石的二次判断阈值(0.0,0.5~1)。如果CNN结果为矿石,且概率<=morewaste_prob,
 *                        那么我们认为这不是真正的矿石,其实是废石。
 *                        morewaste_prob=0.0,即表示不做阈值判断,完全相信CNN矿石的结果;
 *                        morewaste_prob越大,则抛废率越大;
 * */
linkuang::linkuang(int imgsize,float lesswaste_prob,float morewaste_prob) {
    // TODO Auto-generated constructor stub
    standard_rows=imgsize;//48;
    standard_cols=imgsize;//64

    lesswastethresh=lesswaste_prob;
    morewastethresh=morewaste_prob;
    getimgsindex=0;
    showtestindex=0;

    std::string graphpath="/home/jumper/xrt/reference/cnnmodel/model.pb";
//    std::string modelpath="/home/jumper/xrt/reference/model/model_jinhuo0.7/model";

    ///////CNN initiation--
    tensorflow::Status status = NewSession(tensorflow::SessionOptions(), &session);
    if (!status.ok())
    {
        throw std::runtime_error("ERROR: linkuang CNN NewSession() init failed...");
    }

    tensorflow::GraphDef graphdef;
    tensorflow::Status status_load = ReadBinaryProto(tensorflow::Env::Default(), graphpath, &graphdef);
    if (!status_load.ok())
    {
        std::cout << status_load.ToString() <<std::endl;
        throw std::runtime_error("ERROR: Loading model failed...");
    }

    tensorflow::Status status_create = session->Create(graphdef);
    if (!status_create.ok())
    {
        std::cerr < std::endl;
        throw std::runtime_error("ERROR: Creating graph in session failed...");
    }
}


/*单个石头CNN预测
 *输入:highlittleimg------单独石头的高能小图,CV_16UC1,背景是原图
 *       lowlittleimg-------单独石头的低能小图,CV_16UC1,必须是已经与高能对齐的小图,背景是0
 *输出:label---表示此石头的类别
 *             0:废石;
 *               1:矿石;
 *return :-1:模型预测失败
 *        -2:预测成功,但比较概率得到类别失败
 *        0 :成功
 * */
int linkuang::linkuangSingleInference(cv::Mat &cnncolorimg,cv::Mat &outputimg)
{
    Mat standardinput(standard_rows, standard_cols, CV_8UC1);
    resize(cnncolorimg,standardinput,Size(standard_cols,standard_rows),0,0,0);

    //CNN start...和训练做相同的预处理
    tensorflow::Tensor resized_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1,standard_rows,standard_cols,1}));
    float *imgdata = resized_tensor.flat<float>().data();

    Mat cnninputImg(standard_rows, standard_cols, CV_32FC1, imgdata);
    standardinput.convertTo(cnninputImg,CV_32FC1);
    cnninputImg=cnninputImg/255;

    //CNN input
    std::vectorstring, tensorflow::Tensor> > inputs;
    std::string Input1Name = "input_1_1:0";
    inputs.push_back(std::make_pair(Input1Name, resized_tensor));

    //CNN predict
    std::vector outputs;
    std::string output="output_1:0";

    tensorflow::Status status_run = session->Run({{Input1Name,resized_tensor}}, {output}, {}, &outputs);
    if (!status_run.ok()) {
       std::cout <<"ERROR: RUN failed in real inference()..."<< status_run.ToString() << "\n";
       return -1;
    }

    int flag=getOutputImg(outputs[0],outputimg);
    if(flag!=0)
    {
        std::cout <<"ERROR: RUN failed in getCnnRealLabel()..."<<std::endl;
        return -2;
    }

    showtestindex++;

    return 0;
}

int linkuang::getOutputImg(tensorflow::Tensor &output,cv::Mat &outputimg)
{
    int ndim2 = output.shape().dims();

    auto tmap = output.tensor<float, 3>();        //

//      cout<//why not limited in [standard_rows,standard_cols,1] as python ??

    for(int r=0;r!=standard_rows;r++)
    {
        for(int c=0;c!=standard_cols;c++)
        {
            float value=tmap(r,c,2);
            cout<"\t";
            outputimg.ptr(r)[c]=255*value;
        }
        cout<<endl;
    }
    cout<endl;

    return 0;
}


//得到真正的标签,废石进行二次判断
int linkuang::getCnnRealLabel(tensorflow::Tensor &probabilities,int &output_class_id,float &output_prob)
{
      int ndim2 = probabilities.shape().dims();             // Get the dimension of the tensor
      auto tmap = probabilities.tensor<float, 2>();        // Tensor Shape: [batch_size, target_class_num]
      int output_dim = probabilities.shape().dim_size(1);  // Get the target_class_num from 1st dimension

      output_class_id=0;
      float primerprob=tmap(0, 0);
      if(tmap(0, 1)>primerprob)
      {
          primerprob=tmap(0, 1);
          output_class_id=1;
      }

      output_prob=primerprob;

      return 0;
}


linkuang::~linkuang() {
    // TODO Auto-generated destructor stub
    tensorflow::Status freestatus=session->Close();
    if (!freestatus.ok())
    {
        throw std::runtime_error("ERROR: close session...");
    }
}
#include 
#include 
#include 
#include 

#include "linkuang.h"

#include 
#include 
#include 

#include 
using namespace tbb;

using namespace cv;
using namespace std;


void bwthresh2(Mat &tiffimg,ushort th,Mat &bwwhole);


//for cnn
int main()
{
     char srcimg[400]={0};

     linkuang linkuangcnn(112,0.0f,0.0f);

//     for(int index=21;index<=100;index++)
     for(int index=34;index<=34;index++)
     {
        sprintf(srcimg,"/home/jumper/xrt/reference/imgs/20210320/%d_low.tiff",index);
        Mat low_energy_image=imread(srcimg,IMREAD_UNCHANGED);
        if(low_energy_image.empty())
        {
            cout<<"no low image data!"<<endl;
            continue;
        }
        Mat lowimggray=imread(srcimg,0);

        int rows = low_energy_image.rows;
        int cols = low_energy_image.cols;

        Mat wholebwimg=Mat::zeros(rows,cols,CV_8UC1);
        bwthresh2(low_energy_image,43000,wholebwimg);

        vector > contours;
        contours.clear();
        findContours(wholebwimg,contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
        Mat lowmask(rows,cols,CV_8UC1,Scalar(0));
        cv::drawContours(lowmask,contours,-1,Scalar(255),-1);

//        int id=0;//

        const int rstep=200;
        const int cstep=208;

        double timeStart = (double)cv::getTickCount();

        vector rectsall;
        for(int r=0;rrstep)
        {
            for(int c=0;ccstep)
            {
                Rect rect(c,r,cstep,rstep);
                rectsall.push_back(rect);
            }
        }

        int sectionsize=rectsall.size();

//        tbb::parallel_for(0,sectionsize,[&](int i)
        for(int i=0;i!=1;i++)//rectsall.size();i++)
        {
            Mat inputimg(rstep,cstep,CV_8UC1,Scalar(255));
            lowimggray(rectsall[i]).copyTo(inputimg,lowmask(rectsall[i]));

            Mat output(112,112,CV_8UC1,Scalar(255));
            int infeflag = linkuangcnn.linkuangSingleInference(inputimg, output);

//            imwrite("output.png",output);

//            sprintf(srcimg,"/home/jumper/xrt/reference/imgs/xiangan_cnn/%d_%d_srclow.png",index,id);
//            imwrite(srcimg,output);
//            id++;
        }//);

        double nTime = ((double)cv::getTickCount() - timeStart) / cv::getTickFrequency()*1000;
        cout<<"image "<" time: "<" ms!"<<endl;
    }

    return 0;
}


void bwthresh2(Mat &tiffimg,ushort th,Mat &bwwhole)
{
    int rows = tiffimg.rows;
    int cols = tiffimg.cols;
    for(int r =0;r)
    {
        for(int c = 0;c)
        {
            ushort value=tiffimg.ptr<ushort>(r)[c];
            if(value<th)
            {
                bwwhole.ptr(r)[c]=255;
            }
        }
    }
}

可是我看C++版本auto tmap = output.tensor(); 这个得到的结果tmap的确也是3维数据,但是却不是[rows,cols,1],我访问[2000,2000,2000]都有数据,我根本不知道有多大。好像tmap.shape().dims()会报错,不知道怎么输出其shape。但是如果我只把tmap的[rows,cols,0]拿来作为我的网络分割结果图存下来,看起来图片又与python下的结果图一致。Why?我对比了下两幅图的像素值:位置差不多,但像素值有较大差别。

话说我都没见过人使用tensorflow c++推理得到结果图,都没有相关资料?!

如果直接调用opencv::dnn模块,与python下结果是一致的!但是耗时太长,所以准备改成TBB并行:

#include 
#include 
#include 
#include 

#include 

#include "jinXingCnn.h"

#include 
#include 
#include 

#include 
using namespace tbb;

using namespace cv;
using namespace std;

void bwthresh3(Mat &tiffimg,ushort th,Mat &bwwhole);

int main()
{
     char srcimg[400]={0};

     cv::dnn::Net thenet=cv::dnn::readNetFromTensorflow("/home/jumper/xrt/reference/cnnmodel/model.pb");

     for(int index=21;index<=56;index++)
     {
        sprintf(srcimg,"/home/jumper/xrt/reference/imgs/20210320/%d_low.tiff",index);
        Mat low_energy_image=imread(srcimg,IMREAD_UNCHANGED);
        if(low_energy_image.empty())
        {
            cout<<"no low image data!"<<endl;
            continue;
        }

        Mat low_energy_image8bit=imread(srcimg,0);

        int rows = low_energy_image.rows;
        int cols = low_energy_image.cols;

        Mat wholebwimg=Mat::zeros(rows,cols,CV_8UC1);
        bwthresh3(low_energy_image,43000,wholebwimg);

        vector > contours;
        contours.clear();
        findContours(wholebwimg,contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
        Mat lowmask(rows,cols,CV_8UC1,Scalar(0));
        cv::drawContours(lowmask,contours,-1,Scalar(255),-1);

        const int rstep=200;
        const int cstep=208;

        vector rectsall;
        for(int r=0;rrstep)
        {
            for(int c=0;ccstep)
            {
                Rect rect(c,r,cstep,rstep);
                rectsall.push_back(rect);
            }
        }

        int sectionsize=rectsall.size();

        tbb::parallel_for(0,sectionsize,[&](int id)
//        for(int id=0;id!=sectionsize;id++)
        {
            Rect rect=rectsall[id];
            Mat lowlittle(rstep,cstep,CV_8UC1,Scalar(255));
            low_energy_image8bit(rect).copyTo(lowlittle,lowmask(rect));

            Mat blob=cv::dnn::blobFromImage(lowlittle,1.0/255,Size(112,112));
            thenet.setInput(blob);
            Mat output=thenet.forward();
            Mat detectionMat(output.size[2],output.size[3],CV_32F,output.ptr<float>());

            Mat grayoutput=detectionMat*255;
//            sprintf(srcimg,"/home/jumper/xrt/reference/imgs/xiangan_cnn/%d_%d_srclowcv.png",index,id);
//            imwrite(srcimg,grayoutput);
        });

    }

    return 0;
}

但是发现并行就会报错:

*** Error in `./xrtCNNwithoutParallel': double free or corruption (!prev): 0x00007f8424005f50 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f84321a17f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8038a)[0x7f84321aa38a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f84321ae58c]
/usr/local/lib/libopencv_world.so.4.5(+0xc81316)[0x7f8440345316]
/usr/local/lib/libopencv_world.so.4.5(+0xc85a59)[0x7f8440349a59]
/usr/local/lib/libopencv_world.so.4.5(_ZN2cv3dnn14dnn4_v202103013Net7forwardERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0xc2)[0x7f844034a2c2]
./xrtCNNwithoutParallel[0x40c667]
./xrtCNNwithoutParallel[0x40ce8b]
/usr/local/lib/libtbb.so(_ZN3tbb8internal16custom_schedulerINS0_20IntelSchedulerTraitsEE19process_bypass_loopERNS0_20context_guard_helperILb0EEEPNS_4taskEl+0x225)[0x7f843f4a5f45]
/usr/local/lib/libtbb.so(_ZN3tbb8internal16custom_schedulerINS0_20IntelSchedulerTraitsEE18local_wait_for_allERNS_4taskEPS4_+0xfe)[0x7f843f4a62ce]
/usr/local/lib/libtbb.so(_ZN3tbb8internal5arena7processERNS0_17generic_schedulerE+0x187)[0x7f843f4abc67]
/usr/local/lib/libtbb.so(_ZN3tbb8internal6market7processERN3rml3jobE+0x20)[0x7f843f4b1070]
/usr/local/lib/libtbb.so(_ZN3tbb8internal3rml14private_worker3runEv+0x4c)[0x7f843f4b2bcc]
/usr/local/lib/libtbb.so(_ZN3tbb8internal3rml14private_worker14thread_routineEPv+0x9)[0x7f843f4b2e09]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f8431d106ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f843223151d]
======= Memory map: ========
00400000-00411000 r-xp 00000000 08:06 5774704                            /home/jumper/xrt/parallel/xrtCNNwithoutParallel/Release/xrtCNNwithoutParallel
00610000-00611000 rw-p 00010000 08:06 5774704                            /home/jumper/xrt/parallel/xrtCNNwithoutParallel/Release/xrtCNNwithoutParallel
00f36000-03d7d000 rw-p 00000000 00:00 0                                  [heap]
7f8408000000-7f8408022000 rw-p 00000000 00:00 0 
7f8408022000-7f840c000000 ---p 00000000 00:00 0 
7f8410000000-7f841063e000 rw-p 00000000 00:00 0 
7f841063e000-7f8414000000 ---p 00000000 00:00 0 
7f8418000000-7f841863e000 rw-p 00000000 00:00 0 
7f841863e000-7f841c000000 ---p 00000000 00:00 0 
7f841c000000-7f841c021000 rw-p 00000000 00:00 0 
7f841c021000-7f8420000000 ---p 00000000 00:00 0 
7f84237fe000-7f84237ff000 ---p 00000000 00:00 0 
7f84237ff000-7f8423bff000 rw-p 00000000 00:00 0 
7f8423bff000-7f8423c00000 ---p 00000000 00:00 0 
7f8423c00000-7f8424000000 rw-p 00000000 00:00 0 
7f8424000000-7f8424021000 rw-p 00000000 00:00 0 
7f8424021000-7f8428000000 ---p 00000000 00:00 0 
7f8428000000-7f8428021000 rw-p 00000000 00:00 0 
7f8428021000-7f842c000000 ---p 00000000 00:00 0 
7f842c000000-7f842c021000 rw-p 00000000 00:00 0 
7f842c021000-7f8430000000 ---p 00000000 00:00 0 
7f843007a000-7f843007b000 ---p 00000000 00:00 0 
7f843007b000-7f843047b000 rw-p 00000000 00:00 0 
7f843047b000-7f843047c000 ---p 00000000 00:00 0 
7f843047c000-7f843087c000 rw-p 00000000 00:00 0 
7f843087c000-7f843087d000 ---p 00000000 00:00 0 
7f843087d000-7f8430c7d000 rw-p 00000000 00:00 0 
7f8430c7d000-7f8430c7e000 ---p 00000000 00:00 0 
7f8430c7e000-7f843107e000 rw-p 00000000 00:00 0 
7f843107e000-7f843107f000 ---p 00000000 00:00 0 
7f843107f000-7f843147f000 rw-p 00000000 00:00 0 
7f843147f000-7f84314b5000 r-xp 00000000 08:06 18222463                   /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
7f84314b5000-7f84316b4000 ---p 00036000 08:06 18222463                   /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
7f84316b4000-7f84316b5000 r--p 00035000 08:06 18222463                   /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
7f84316b5000-7f84316b6000 rw-p 00036000 08:06 18222463                   /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
7f84316b6000-7f84316cf000 r-xp 00000000 08:06 9044223                    /lib/x86_64-linux-gnu/libz.so.1.2.8
7f84316cf000-7f84318ce000 ---p 00019000 08:06 9044223                    /lib/x86_64-linux-gnu/libz.so.1.2.8
7f84318ce000-7f84318cf000 r--p 00018000 08:06 9044223                    /lib/x86_64-linux-gnu/libz.so.1.2.8
7f84318cf000-7f84318d0000 rw-p 00019000 08:06 9044223                    /lib/x86_64-linux-gnu/libz.so.1.2.8
7f84318d0000-7f8431900000 r-xp 00000000 08:06 9047795                    /lib/x86_64-linux-gnu/libpng16.so.16.20.0
7f8431900000-7f8431aff000 ---p 00030000 08:06 9047795                    /lib/x86_64-linux-gnu/libpng16.so.16.20.0
7f8431aff000-7f8431b00000 r--p 0002f000 08:06 9047795                    /lib/x86_64-linux-gnu/libpng16.so.16.20.0
7f8431b00000-7f8431b01000 rw-p 00030000 08:06 9047795                    /lib/x86_64-linux-gnu/libpng16.so.16.20.0
7f8431b01000-7f8431b08000 r-xp 00000000 08:06 9055406                    /lib/x86_64-linux-gnu/librt-2.23.so
7f8431b08000-7f8431d07000 ---p 00007000 08:06 9055406                    /lib/x86_64-linux-gnu/librt-2.23.so
7f8431d07000-7f8431d08000 r--p 00006000 08:06 9055406                    /lib/x86_64-linux-gnu/librt-2.23.so
7f8431d08000-7f8431d09000 rw-p 00007000 08:06 9055406                    /lib/x86_64-linux-gnu/librt-2.23.so
7f8431d09000-7f8431d21000 r-xp 00000000 08:06 9055398                    /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8431d21000-7f8431f20000 ---p 00018000 08:06 9055398                    /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8431f20000-7f8431f21000 r--p 00017000 08:06 9055398                    /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8431f21000-7f8431f22000 rw-p 00018000 08:06 9055398                    /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8431f22000-7f8431f26000 rw-p 00000000 00:00 0 
7f8431f26000-7f8431f29000 r-xp 00000000 08:06 9055403                    /lib/x86_64-linux-gnu/libdl-2.23.so
7f8431f29000-7f8432128000 ---p 00003000 08:06 9055403                    /lib/x86_64-linux-gnu/libdl-2.23.so
7f8432128000-7f8432129000 r--p 00002000 08:06 9055403                    /lib/x86_64-linux-gnu/libdl-2.23.so
7f8432129000-7f843212a000 rw-p 00003000 08:06 9055403                    /lib/x86_64-linux-gnu/libdl-2.23.so
7f843212a000-7f84322ea000 r-xp 00000000 08:06 9055416                    /lib/x86_64-linux-gnu/libc-2.23.so
7f84322ea000-7f84324ea000 ---p 001c0000 08:06 9055416                    /lib/x86_64-linux-gnu/libc-2.23.so
7f84324ea000-7f84324ee000 r--p 001c0000 08:06 9055416                    /lib/x86_64-linux-gnu/libc-2.23.so
7f84324ee000-7f84324f0000 rw-p 001c4000 08:06 9055416                    /lib/x86_64-linux-gnu/libc-2.23.so
7f84324f0000-7f84324f4000 rw-p 00000000 00:00 0 
7f84324f4000-7f843250b000 r-xp 00000000 08:06 9055394                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f843250b000-7f843270a000 ---p 00017000 08:06 9055394                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f843270a000-7f843270b000 r--p 00016000 08:06 9055394                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f843270b000-7f843270c000 rw-p 00017000 08:06 9055394                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f843270c000-7f8432814000 r-xp 00000000 08:06 9055411                    /lib/x86_64-linux-gnu/libm-2.23.so
7f8432814000-7f8432a13000 ---p 00108000 08:06 9055411                    /lib/x86_64-linux-gnu/libm-2.23.so
7f8432a13000-7f8432a14000 r--p 00107000 08:06 9055411                    /lib/x86_64-linux-gnu/libm-2.23.so
7f8432a14000-7f8432a15000 rw-p 00108000 08:06 9055411                    /lib/x86_64-linux-gnu/libm-2.23.so
7f8432a15000-7f8432be8000 r-xp 00000000 08:06 18219195                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f8432be8000-7f8432de8000 ---p 001d3000 08:06 18219195                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f8432de8000-7f8432df3000 r--p 001d3000 08:06 18219195                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f8432df3000-7f8432df6000 rw-p 001de000 08:06 18219195                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
7f8432df6000-7f8432df9000 rw-p 00000000 00:00 0 
7f8432df9000-7f8434724000 r-xp 00000000 08:06 3941847                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_framework.so.2.0.0
7f8434724000-7f8434725000 ---p 0192b000 08:06 3941847                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_framework.so.2.0.0
7f8434725000-7f84347b9000 r--p 0192b000 08:06 3941847                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_framework.so.2.0.0
7f84347b9000-7f84347bf000 rw-p 019bf000 08:06 3941847                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_framework.so.2.0.0
7f84347bf000-7f84347d2000 rw-p 00000000 00:00 0 
7f84347d2000-7f843f00f000 r-xp 00000000 08:06 3941844                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_cc.so.2.0.0
7f843f00f000-7f843f415000 r--p 0a83c000 08:06 3941844                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_cc.so.2.0.0
7f843f415000-7f843f42d000 rw-p 0ac42000 08:06 3941844                    /home/jumper/workspace/tensorflow_cc/lib/libtensorflow_cc.so.2.0.0
7f843f42d000-7f843f48c000 rw-p 00000000 00:00 0 
7f843f48c000-7f843f4c2000 r-xp 00000000 08:06 18618449                   /usr/local/lib/libtbb.so
7f843f4c2000-7f843f6c2000 ---p 00036000 08:06 18618449                   /usr/local/lib/libtbb.so
7f843f6c2000-7f843f6c4000 rw-p 00036000 08:06 18618449                   /usr/local/lib/libtbb.so
7f843f6c4000-7f8443873000 r-xp 00000000 08:06 18618452                   /usr/local/lib/libopencv_world.so.4.5.2
7f8443873000-7f8443a73000 ---p 041af000 08:06 18618452                   /usr/local/lib/libopencv_world.so.4.5.2
7f8443a73000-7f8443b5f000 rw-p 041af000 08:06 18618452                   /usr/local/lib/libopencv_world.so.4.5.2
7f8443b5f000-7f8443d77000 rw-p 00000000 00:00 0 
7f8443d77000-7f8443d9d000 r-xp 00000000 08:06 9055408                    /lib/x86_64-linux-gnu/ld-2.23.so
7f8443f55000-7f8443f7e000 rw-p 00000000 00:00 0 
7f8443f9b000-7f8443f9c000 rw-p 00000000 00:00 0 
7f8443f9c000-7f8443f9d000 r--p 00025000 08:06 9055408                    /lib/x86_64-linux-gnu/ld-2.23.so
7f8443f9d000-7f8443f9e000 rw-p 00026000 08:06 9055408                    /lib/x86_64-linux-gnu/ld-2.23.so
7f8443f9e000-7f8443f9f000 rw-p 00000000 00:00 0 
7ffe2e8b1000-7ffe2e8d2000 rw-p 00000000 00:00 0                          [stack]
7ffe2e93e000-7ffe2e940000 r--p 00000000 00:00 0                          [vvar]
7ffe2e940000-7ffe2e942000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
已放弃 (核心已转储)

为什么?是dnn不支持并行吗??