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) подготовиться. "