thtrieu / darkflow

Translate darknet to tensorflow. Load trained weights, retrain/fine-tune using tensorflow, export constant graph def to mobile devices
GNU General Public License v3.0
6.13k stars 2.08k forks source link

No objects detected with Yolov2 and TensorFlow Lite (Confidence scores are low) #1167

Open mustansarsaeed opened 4 years ago

mustansarsaeed commented 4 years ago

I am trying to run yolov2 with TensorFlow Lite in Android. I have integrated Yolo v2 in Android but it is not detecting any images. In order to user YoLo v2 model in Android, I have followed following steps:

  1. Downloaded weights using curl https://pjreddie.com/media/files/yolov2-tiny.weights -o yolov2-tiny.weights

  2. Downloaded config file using curl https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov2-tiny.cfg -o yolov2-tiny.cfg

  3. Downloaded labels file curl https://raw.githubusercontent.com/pjreddie/darknet/master/data/coco.names -o label.txt Converted weights to tensor flow protocol buffer using flow --model yolov2-tiny.cfg --load yolov2-tiny.weights --savepb

  4. Converted tensor flow buffers to tensor flow lite using tflite_convert --graph_def_file='/home/mustansar/Softwares/darkflow/built_graph/yolov2-tiny.pb' --output_file='/home/mustansar/Softwares/darkflow/built_graph/yolov2-tiny.lite' --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shape=1,416,416,3 --input_array=input --output_array=output

In the end I have two files yolov2-tiny.lite and yolov2-tiny.meta. In Android I am using dependency: implementation('org.tensorflow:tensorflow-lite:0.0.0-nightly') { changing = true }

I have loaded model and processing the image as :

Detector Class:

@Override
  public List<Recognition> recognizeImage(final Bitmap bitmap) {
    convertBitmapToByteBuffer(bitmap);

    tfLite.run(imgData, outputLocations);

    return findRecognitionsUsingTensorExample();
  }

findRecognitionUsingTensorExample()

public ArrayList<Recognition> findRecognitionsUsingTensorExample() {
    float[][][] output = outputLocations[0];
//
    // Find the best detections.
    final PriorityQueue<Recognition> pq =
            new PriorityQueue<Recognition>(
                    1,
                    new Comparator<Recognition>() {
                      @Override
                      public int compare(final Recognition lhs, final Recognition rhs) {
                        // Intentionally reversed to put high confidence at the head of the queue.
                        return Float.compare(rhs.getConfidence(), lhs.getConfidence());
                      }
                    });

    for (int y = 0; y < gridHeight; ++y) {
      for (int x = 0; x < gridWidth; ++x) {
        for (int b = 0; b < NUM_BOXES_PER_BLOCK; ++b) {
          final int offset =
                  (gridWidth * (NUM_BOXES_PER_BLOCK * (NUM_CLASSES + 5))) * y
                          + (NUM_BOXES_PER_BLOCK * (NUM_CLASSES + 5)) * x
                          + (NUM_CLASSES + 5) * b;

          if(offset >= 416 || offset + 1 >= 416) continue;

          final float xPos = (x + expit(output[y][x][offset + 0])) * blockSize;
          final float yPos = (y + expit(output[y][x][offset + 1])) * blockSize;

          final float w = (float) (Math.exp(output[y][x][offset + 2]) * ANCHORS[2 * b + 0]) * blockSize;
          final float h = (float) (Math.exp(output[y][x][offset + 3]) * ANCHORS[2 * b + 1]) * blockSize;

          final RectF rect =
                  new RectF(
                          Math.max(0, xPos - w / 2),
                          Math.max(0, yPos - h / 2),
                          Math.min(INP_IMG_WIDTH - 1, xPos + w / 2),
                          Math.min(INP_IMG_HEIGHT - 1, yPos + h / 2));
          final float confidence = expit(output[y][x][offset + 4]);

          int detectedClass = -1;
          float maxClass = 0;

          final float[] classes = new float[NUM_CLASSES];
          for (int c = 0; c < NUM_CLASSES; ++c) {
            classes[c] = output[x][y][offset + 5 + c];
          }
          softmax(classes);

          for (int c = 0; c < NUM_CLASSES; ++c) {
            if (classes[c] > maxClass) {
              detectedClass = c;
              maxClass = classes[c];
            }
          }

          final float confidenceInClass = maxClass * confidence;
          if (confidenceInClass > THRESHOLD) {
            LOGGER.i(
                    "%s (%d) %f %s", LABELS[detectedClass], detectedClass, confidenceInClass, rect);
            pq.add(new Recognition("" + offset, LABELS[detectedClass], confidenceInClass, rect));
          }
        }
      }
    }
    final ArrayList<Recognition> recognitions = new ArrayList<Recognition>();
    for (int i = 0; i < Math.min(pq.size(), MAX_RESULTS); ++i) {
      recognitions.add(pq.poll());
    }

    return recognitions;
  }

From yolov2-tiny.meta, I have used configuration i.e. classes=80, threshold=0.6, image size = 416x416, labels from file and anchors from meta file. I am unable to find the missing element.

> Can anyone please guide why objects are not being detected?