0

I am trying to process images on Jetson device with Python 3.6.9 with Yolov7 tiny and darknet framework. The code works perfectly on my local MAC (2021, M1) but on Jetson I am getting an error.

Thank you very much for your help!

import cv2
import numpy as np
        
class YoloDetection():
    def __init__(self, model_path: str, config: str, classes: str, width: int, height: int,
                 scale=.00392, thr=0.1, nms=0.4,#00392#.4
                 backend=0,
                 framework=3,
                 target=0,
                 mean=[0, 0, 0]):
        
        super(YoloDetection,self).__init__()
        choices = ['caffe', 'tensorflow', 'torch', 'darknet']
        backends = (
            cv2.dnn.DNN_BACKEND_DEFAULT, cv2.dnn.DNN_BACKEND_HALIDE, cv2.dnn.DNN_BACKEND_INFERENCE_ENGINE,
            cv2.dnn.DNN_BACKEND_OPENCV)
        targets = (
            cv2.dnn.DNN_TARGET_CPU, cv2.dnn.DNN_TARGET_OPENCL, cv2.dnn.DNN_TARGET_OPENCL_FP16, cv2.dnn.DNN_TARGET_MYRIAD)

        self.__confThreshold = thr
        self.__nmsThreshold = nms
        self.__mean = mean
        self.__scale = scale
        self.__width = width
        self.__height = height

        # Load a network
        self.__net = cv2.dnn.readNet(model_path, config, choices[framework])
        self.__net.setPreferableBackend(backends[backend])
        self.__net.setPreferableTarget(targets[target])
        self.__classes = None

        if classes:
            with open(classes, 'rt') as f:
                self.__classes = f.read().rstrip('\n').split('\n')


    def get_output_layers_name(self, net):
        return net.getUnconnectedOutLayersNames()

    def post_process_output(self, frame, outs):
        frame_height = frame.shape[0]
        frame_width = frame.shape[1]

        class_ids = []
        confidences = []
        boxes = []

        class_ids = []
        confidences = []
        boxes = []
        for out in outs:
            for detection in out:
                scores = detection[5:]
                class_id = np.argmax(scores)
                confidence = scores[class_id]
                if confidence > self.__confThreshold:
                    center_x = int(detection[0] * frame_width)
                    center_y = int(detection[1] * frame_height)
                    width = int(detection[2] * frame_width)
                    height = int(detection[3] * frame_height)
                    left = center_x - width / 2
                    top = center_y - height / 2
                    class_ids.append(class_id)
                    confidences.append(float(confidence))
                    boxes.append([left, top, width, height])

        
        indices = cv2.dnn.NMSBoxes(boxes, confidences, self.__confThreshold, self.__nmsThreshold)
        return (indices, boxes, confidences, class_ids)

    def process_frame(self, frame: np.ndarray):
        frame_height = frame.shape[0]
        frame_width = frame.shape[1]

        blob = cv2.dnn.blobFromImage(frame, self.__scale, (self.__width, self.__height), self.__mean, True, crop=False)

        # Run a model
        self.__net.setInput(blob)
        outs = self.__net.forward(self.get_output_layers_name(self.__net))
        (indices, boxes, confidences, class_ids) = self.post_process_output(frame, outs)
        detected_objects = []

        for i in indices:
            
            box = boxes[i]
            left = box[0]
            top = box[1]
            width = box[2]
            height = box[3]
            x = int(left)
            y = int(top)
            nw = int(width)
            nh = int(height)
            if x < 0:
                x = 0
            if y < 0:
                y = 0
            if x + nw > frame_width:
                nw = frame_width - x
            if y + nh > frame_height:
                nh = frame_height - y
            detected_objects.append([self.__classes[class_ids[i]], x, y, nw, nh, confidences[i]])
        return detected_objects

The error I get is

Traceback (most recent call last):
  ...
  File "main.py", line 267, in start_detection
    detections = model.process_frame(frame_model)
  File "/home/jetson/plate-jetson/plate-jetson/yolo.py", line 87, in process_frame
    box = boxes[i]
TypeError: only integer scalar arrays can be converted to a scalar index

When I am printing 'indices' I get:

[[  508]
 [ 8739]
 [ 8417]
 ...
 [ 2405]
 [ 9898]
 [10138]]

Thank you very much for your help!

I want to run darknet as object detector.

Matthias
  • 3
  • 2

1 Answers1

0

It seems to me that your indices is a container of containers indicated by the double bracket:

[[ 508]
...
[10138]]

So what you are currently doing is box = boxes[ [[508][8739][8417]...] ].
What you probably want is box = boxes[508] then later box = boxes[8739] and so on. A simple solution would be:

for ind in indices:
    for i in ind:
        box = boxes[i]
        ...
Sn3nS
  • 36
  • 6
  • My error is particular to darknet and OpenCV. Simply manipulating the output is not solving it, but thank you for your time. – Matthias Mar 28 '23 at 11:07