Проблема при запуске «mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite» на пограничном TPU с использованием Tensorflow Lite в c ++ - PullRequest
0 голосов
/ 05 февраля 2020
    const std::string model_path = "/home/pi/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite";
    std::unique_ptr<tflite::FlatBufferModel> model =
    tflite::FlatBufferModel::BuildFromFile(model_path.c_str());

    //creating edge TPU
    std::shared_ptr<edgetpu::EdgeTpuContext> edgetpu_context =
        edgetpu::EdgeTpuManager::GetSingleton()->OpenDevice();

    // Build the interpreter
    tflite::ops::builtin::BuiltinOpResolver resolver;
    std::unique_ptr<tflite::Interpreter> interpreter;
    resolver.AddCustom(edgetpu::kCustomOp, edgetpu::RegisterCustomOp());
    tflite::InterpreterBuilder(*model.get(), resolver)(&interpreter);
    interpreter->SetExternalContext(kTfLiteEdgeTpuContext, edgetpu_context.get());
    interpreter->SetNumThreads(1);

    if (edgetpu_context == nullptr)
    {
        cout<< "TPU cannot be found or opened!";
    }

    // Resize input tensors, if desired.

     TfLiteTensor* output_locations = nullptr;
     TfLiteTensor* output_classes = nullptr;
     TfLiteTensor* num_detections = nullptr;
     // TfLiteTensor* scores = nullptr;
     auto cam = cv::VideoCapture(0);
     // auto cam = cv::VideoCapture("../demo.mp4");

     std::vector<std::string> labels;

     auto file_name="/home/pi/labelmap.txt";
     std::ifstream input( file_name );
     for( std::string line; getline( input, line ); )
     {
         labels.push_back( line);

     }

     auto cam_width =cam.get(CV_CAP_PROP_FRAME_WIDTH);
     auto cam_height = cam.get(CV_CAP_PROP_FRAME_HEIGHT);
     while (true) {
         cv::Mat image0;
         auto success = cam.read(image0);
         if (!success) {
             std::cout << "cam fail" << std::endl;
             break;
         }
         cv::Mat image;
         resize(image0, image, Size(300,300));
         interpreter->AllocateTensors();

         auto input = interpreter->typed_tensor<float>(0);
         //uchar* input = interpreter->typed_input_tensor<uchar>(0);

         // feed input
         auto image_height=image.rows;
         auto image_width=image.cols;
         auto image_channels=3;
         int number_of_pixels = image_height * image_width * image_channels;
         int base_index = 0;
         // copy image to input as input tensor
         //memcpy(interpreter->typed_input_tensor<uchar>(0), image.data, image.total() * image.elemSize());
         //interpreter->SetAllowFp16PrecisionForFp32(true);

         int count1=0;
         for(int i=0;i<image.rows;i++){
             for(int j=0;j<image.cols;j++)
                {
                  cv::Vec3f pixel= image.at<cv::Vec3f>(i,j);
                  for(int k = 0; k < image.channels(); k++) {
                         input[count1] = pixel.val[k];
                         count1++;
                  }
                }
         }

         interpreter->SetNumThreads(1);

         interpreter->Invoke();
         output_locations = interpreter->tensor(interpreter->outputs()[0]);
         auto output_data = output_locations->data.f;
         std::vector<float> locations;
         std::vector<float> cls;

         output_classes   = interpreter->tensor(interpreter->outputs()[1]);
         auto out_cls = output_classes->data.f;
         num_detections   = interpreter->tensor(interpreter->outputs()[3]);
         auto nums = num_detections->data.f;
         for (int i = 0; i < 20; i++){
             auto output = output_data[i];
             locations.push_back(output);
             cls.push_back(out_cls[i]);
         }
         int count=0;
         std::vector<Object> objects;

         for(int j = 0; j <locations.size(); j+=4){
                 auto ymin=locations[j]*cam_height;
                 auto xmin=locations[j+1]*cam_width;
                 auto ymax=locations[j+2]*cam_height;
                 auto xmax=locations[j+3]*cam_width;
                 auto width= xmax - xmin;
                 auto height= ymax - ymin;

                 // auto rec = Rect(xmin, ymin, width, height);

                 float score = expit(nums[count]); // How has this to be done?
                 // std::cout << "score: "<< score << std::endl;
                 // if (score < 0.5f) continue;

                 // auto id=outputClasses;
                 Object object;
                 object.class_id = cls[count];
                 object.rec.x = xmin;
                 object.rec.y = ymin;
                 object.rec.width = width;
                 object.rec.height = height;
                 object.prob = score;
                 objects.push_back(object);

                 count+=1;


             }
         nms(objects,0.5);
         RNG rng(12345);
         std::cout << "size: "<<objects.size() << std::endl;
         for(int l = 0; l < objects.size(); l++)
          {


                 Object object = objects.at(l);
                 auto score=object.prob;
                 if (score < 0.60f) continue;
                 Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255));
                 auto cls = object.class_id;

                 cv::rectangle(image0, object.rec,color, 1);
                 cv::putText(image0, labels[cls+1], cv::Point(object.rec.x, object.rec.y - 5),
                 cv::FONT_HERSHEY_COMPLEX, .8, cv::Scalar(10, 255, 30));
                 std::cout<< cls<< std::endl;


         }

         cv::imshow("cam", image0);
         auto k = cv::waitKey(30);
         if (k != 255) {
                 break;
         }
    }

После выполнения этого кода я получаю следующую ошибку:

"ОШИБКА: Внутренняя: Неподдерживаемый тип данных в обработчике нестандартного оператора: 0 ОШИБКА: не удалось установить узел 0 (edgetpu-custom-op) подготовиться. "

1 Ответ

0 голосов
/ 07 февраля 2020

Недавно появилось обновление до libedgetpu.so среды выполнения версии 13, которое могло бы вызвать это. Я хотел бы убедиться, что вы работаете с последней версией libtensorflow-lite.a, а также со ссылками на новейшую версию libedgetpu.so

...