2016-03-16 40 views
10

In tensorflow C++ posso caricare un file di immagine nel grafico utilizzandoCome passare un OpenCV Mat in un grafico TENSorflow C++?

tensorflow::Node* file_reader = tensorflow::ops::ReadFile(tensorflow::ops::Const(IMAGE_FILE_NAME, b.opts()),b.opts().WithName(input_name)); 
tensorflow::Node* image_reader = tensorflow::ops::DecodePng(file_reader, b.opts().WithAttr("channels", 3).WithName("png_reader")); 
tensorflow::Node* float_caster = tensorflow::ops::Cast(image_reader, tensorflow::DT_FLOAT, b.opts().WithName("float_caster")); 
tensorflow::Node* dims_expander = tensorflow::ops::ExpandDims(float_caster, tensorflow::ops::Const(0, b.opts()), b.opts()); 
tensorflow::Node* resized = tensorflow::ops::ResizeBilinear(dims_expander, tensorflow::ops::Const({input_height, input_width},b.opts().WithName("size")),b.opts()); 

Per un'applicazione embedded vorrei passare invece un tappetino OpenCV in questo grafico.

Come convertirei Mat su un tensore che potrebbe essere utilizzato come input per tensorflow :: ops :: Cast o tensorflow :: ops :: ExpandDims?

risposta

16

non è direttamente da un CvMat, ma si può vedere un esempio di come inizializzare un tensore da un array in memoria nell'esempio tensorflow Android: https://github.com/tensorflow/tensorflow/blob/0.6.0/tensorflow/examples/android/jni/tensorflow_jni.cc#L173

Si potrebbe iniziare con la creazione di un nuovo tensorflow :: oggetto Tensor, con qualcosa come questo (tutto il codice non testato):

tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, height, width, depth}));

questo crea un oggetto Tensor con valori float, con una dimensione del lotto di 1, e una dimensione di width x height, e con depth canali. Ad esempio, un'immagine 128 wide per 64 alta con 3 canali passerebbe in una forma di {1, 64, 128, 3}. La dimensione del batch viene utilizzata solo quando è necessario passare più immagini in una singola chiamata e per usi semplici è possibile lasciarla come 1.

Quindi si otterrà l'array sottostante dietro il tensore utilizzando una linea come questa:

auto input_tensor_mapped = input_tensor.tensor<float, 4>();

L'oggetto input_tensor_mapped è un'interfaccia per i dati contenuti nel tensore appena creato, e quindi è possibile copiare i propri dati in esso. Qui sto assumendo che tu hai impostato source_data come un puntatore a dati di origine, ad esempio:

const float* source_data = some_structure.imageData;

È quindi possibile scorrere i dati e copiarlo su:

for (int y = 0; y < height; ++y) { 
    const float* source_row = source_data + (y * width * depth); 
    for (int x = 0; x < width; ++x) { 
     const float* source_pixel = source_row + (x * depth); 
     for (int c = 0; c < depth; ++c) { 
      const float* source_value = source_pixel + c; 
      input_tensor_mapped(0, y, x, c) = *source_value; 
     } 
    } 
} 

Ci Sono ovvie opportunità per ottimizzare questo approccio ingenuo, e non ho codice di esempio a disposizione per mostrare come gestire il lato OpenCV di ottenere i dati di origine, ma spero che questo sia utile per iniziare.

1

Avevo provato a eseguire il modello iniziale sul file opencv Mat e il codice seguente ha funzionato per me https://gist.github.com/kyrs/9adf86366e9e4f04addb. Sebbene ci siano alcuni problemi con l'integrazione di opencv e tensorflow. Il codice ha funzionato senza alcun problema per i file .png ma non è stato possibile caricare .jpg e .jpeg. È possibile seguire questo per ulteriori informazioni https://github.com/tensorflow/tensorflow/issues/1924

+0

Il collegamento di sintesi non funziona – Pototo

Problemi correlati