簡體   English   中英

Tensorflow自定義操作與OpenCV未定義符號

[英]Tensorflow custom op with OpenCV undefined symbol

我正在為Tensorflow編寫一個應該加載視頻的自定義操作。 為此,我需要包含OpenCV。

目前,該操作只是嘗試打開VideoCapture並返回空張量。

這是C ++代碼:

#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"


#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/op_kernel.h"

#include <iostream>

using namespace tensorflow;
using namespace cv;
using namespace std;

using shape_inference::ShapeHandle;
using shape_inference::DimensionHandle;

REGISTER_OP("LoadVideo")
    .Input("filename: string")
    .Output("frame: float32")
    .SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) {
        TensorShape outputTensorShape({224, 224, 3});
        ShapeHandle outputShapeHandle;
        c->MakeShapeFromTensorShape(outputTensorShape, &outputShapeHandle);
        c->set_output(0, outputShapeHandle);
        return Status::OK();
    });

class LoadVideoOp : public OpKernel {
 public:
  explicit LoadVideoOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    // Grab the input tensor
    const Tensor& input_tensor = context->input(0);
    auto input = input_tensor.flat<string>();
    string filename = input(0);

    VideoCapture cap = VideoCapture("data/0eRkpTGq5pA.mp4");

    Tensor* output_tensor = NULL;
    OP_REQUIRES_OK(context, context->allocate_output(0, {224, 224, 3}, &output_tensor));

  }
};

REGISTER_KERNEL_BUILDER(Name("LoadVideo").Device(DEVICE_CPU), LoadVideoOp);

然后,我使用以下命令編譯代碼:

g++ -std=c++11 -shared -fPIC \
-I /home/master/anaconda3/envs/tf/lib/python3.6/site-packages/tensorflow/include \
-I ~/anaconda3/envs/tf/include/opencv2/ -I ~/anaconda3/envs/tf/include/opencv/ -O2 \
-L ~/anaconda3/envs/tf/lib \
load_video.cc -o load_video.so \
-lopencv_core -lopencv_videoio -lopencv_highgui \
-lopencv_imgproc -lopencv_video -lopencv_objdetect

當我將編譯的代碼加載到Python腳本(使用tf.load_op_library )並嘗試運行op時,我收到以下錯誤:

tensorflow.python.framework.errors_impl.NotFoundError:lib / ops / load_video.so:undefined symbol:_ZN2cv12VideoCaptureC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

看起來編譯的C ++代碼無法訪問相應的OpenCV對象。 我對C ++編譯和鏈接知之甚少,所以問題可能是我正在以錯誤的方式編譯自定義op。

你能幫助我以這種方式編譯op,它可以通過tensorflow成功加載和運行嗎?

編輯1:

這是我用來加載自定義操作的Python腳本:

import tensorflow as tf
load_video_module = tf.load_op_library('lib/ops/load_video.so')
with tf.Session():
  x = load_video_module.load_video("data/0eRkpTGq5pA.mp4").eval()
  print(x)

錯誤發生在第2行(即嘗試加載已編譯的C ++代碼時)。

解:

在重建OpenCV之后,我成功地編譯並運行了自定義tensorflow操作。 編譯命令是:

g++ -std=c++11 -ggdb -shared -I`python -c 'import tensorflow as tf; print(tf.sysconfig.get_include())'` `pkg-config --cflags opencv` -o load_video.so load_video.cc `pkg-config --libs opencv` -fPIC

您可以使用ldd檢查您的庫是否需要一些丟失的庫。

只需檢查ldd load_video.so

但是,您可能沒有鏈接某些您正在使用的OpenCV方法所需的共享庫。

要確保鏈接並包含所需的每個庫,您可以使用pkg-config

刪除指向OpenCV庫的手動-I-l標志,然后添加pkg-config --libs --cflags opencv ,為您完成全部工作(包括和鏈接庫)

如果您在Linux上運行,請進入包含視頻文件的目錄,然后執行,不帶括號:

sudo chmod 777 (the name of your video file)

這應該讓您的程序訪問視頻文件。 我對C ++知之甚少,但是當TensorFlow被拒絕許可時經常拋出這個錯誤,所以試一試,祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM