2017-12-18 10 views
1

C++でTensorflowを使用してオブジェクトを検出しています。それはうまく動作し、私はいくつかの視覚的なフィードバックを持ってボックスを描画したい。
そこ操作tensorflow :: OPS :: DrawBoundingBoxes私はこれをやらせるだろうですが、問題は次のとおりです。Tensorflow DrawBoundingBoxes C++

  • 私は入力値がボックスのあるべきかを理解していません。

    boxes: 3-D with shape [batch, num_bounding_boxes, 4] containing bounding boxes. 
    
  • 私はこのOPSが存在しない場合、ほぼそのままのように、どこかC++でこの操作を使用する例を見つけることができませんでした。この平均値を何。

このopsが使用されているC++のどこかに例がありますか?チュートリアルやデバッグのために行う基本的なことを聞​​きます。ここで

答えて

1

あなたはこの質問にはまだされている場合、私はOpenCV基本的な方法を使用して、この操作の私の独自の実装を書かれています。対応するクラスラベルを持つボックスのキャプションもサポートしています。

/** Draw bounding box and add caption to the image. 
* Boolean flag _scaled_ shows if the passed coordinates are in relative units (true by default in tensorflow detection) 
*/ 
void drawBoundingBoxOnImage(Mat &image, double yMin, double xMin, double yMax, double xMax, double score, string label, bool scaled=true) { 
    cv::Point tl, br; 
    if (scaled) { 
     tl = cv::Point((int) (xMin * image.cols), (int) (yMin * image.rows)); 
     br = cv::Point((int) (xMax * image.cols), (int) (yMax * image.rows)); 
    } else { 
     tl = cv::Point((int) xMin, (int) yMin); 
     br = cv::Point((int) xMax, (int) yMax); 
    } 
    cv::rectangle(image, tl, br, cv::Scalar(0, 255, 255), 1); 

    // Ceiling the score down to 3 decimals (weird!) 
    float scoreRounded = floorf(score * 1000)/1000; 
    string scoreString = to_string(scoreRounded).substr(0, 5); 
    string caption = label + " (" + scoreString + ")"; 

    // Adding caption of type "LABEL (X.XXX)" to the top-left corner of the bounding box 
    int fontCoeff = 12; 
    cv::Point brRect = cv::Point(tl.x + caption.length() * fontCoeff/1.6, tl.y + fontCoeff); 
    cv::rectangle(image, tl, brRect, cv::Scalar(0, 255, 255), -1); 
    cv::Point textCorner = cv::Point(tl.x, tl.y + fontCoeff * 0.9); 
    cv::putText(image, caption, textCorner, FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(255, 0, 0)); 
} 

/** Draw bounding boxes and add captions to the image. 
* Box is drawn only if corresponding score is higher than the _threshold_. 
*/ 
void drawBoundingBoxesOnImage(Mat &image, 
           tensorflow::TTypes<float>::Flat scores, 
           tensorflow::TTypes<float>::Flat classes, 
           tensorflow::TTypes<float,3>::Tensor boxes, 
           map<int, string> labelsMap, double threshold=0.5) { 
    for (int j = 0; j < scores.size(); j++) 
     if (scores(j) > threshold) 
      drawBoundingBoxOnImage(image, boxes(0,j,0), boxes(0,j,1), boxes(0,j,2), boxes(0,j,3), scores(j), labelsMap[classes(j)]); 
} 

完全な例はhereです。

0

image.pngに2つの四角形を描画し、outout.pngとして保存しますpythonで小さな使用例で、私はそれはあなたを助けるべきであると考えている:

from __future__ import absolute_import 
from __future__ import division 
from __future__ import print_function 

import tensorflow as tf 
import numpy as np 
import PIL.Image as pimg 

if __name__ == '__main__': 
    image = tf.convert_to_tensor(np.array(pimg.open('image.png'), np.float), tf.float32) 
    bbox = tf.convert_to_tensor([[0.1, 0.1, 0.4, 0.4], [0.5, 0.5, 0.6, 0.7]]) 
    with tf.Session() as s: 
     s.run(tf.global_variables_initializer()) 
     output = s.run(tf.image.draw_bounding_boxes(tf.expand_dims(image, 0), tf.expand_dims(bbox, 0))) 
     pimg.fromarray(np.uint8(output[0])).save('output.png') 

boxesは、それぞれの長方形の配列の配列でありますここで、矩形は4つの正規化された浮動小数点[min_y、min_x、max_y、max_x]によって定義されます。

0

私はこれを使って動作させることができました。
ボックスの表示方法やスコアやラベルテキストなどの情報を実際に制御することはできません。場合

Status CreateBoxedTensor(Tensor &input_image, Tensor &input_boxes, Tensor *output) { 
    auto root = Scope::NewRootScope(); 

    // First OP is to convert uint8 image tensor to float for the drawing op to not loose its s* 
    Input imgin(input_image); 
    auto cast_op = Cast(root, imgin, DT_FLOAT); 

    // Next one is the drawing itself 
    Input boxin(input_boxes); 
    auto draw_op = DrawBoundingBoxes(root, cast_op, boxin); 

    // And we convert back to uint8 because it's RGB after all that we want 
    auto cast_back_op = Cast(root, draw_op, DT_UINT8); 

    ClientSession session(root); 
    std::vector<Tensor> out_tensors; 
    TF_RETURN_IF_ERROR(session.Run({cast_back_op}, &out_tensors)); 

    *output = out_tensors[0]; 
    return Status::OK(); 
}