1

I am trying to do object detection with openCV on images already saved on my raspberry pi's file system, but the system reboots when I run the following python script:

import cv2 as cv
import argparse
import sys
import numpy as np
import os.path
import imutils

# Initialize the parameters
confThreshold = 0.25  #Confidence threshold
nmsThreshold = 0.4   #Non-maximum suppression threshold
inpWidth = 416       #Width of network's input image
inpHeight = 416      #Height of network's input image

# Load names of classes
classesFile = "coco.names"
classes = None
with open(classesFile, 'rt') as f:
    classes = f.read().rstrip('\n').split('\n')

# Give the configuration and weight files for the model and load the network using them.
modelConfiguration = "yolov3.cfg"
modelWeights = "yolov3.weights"

net = cv.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)

# Get the names of the output layers
def getOutputsNames(net):
    # Get the names of all the layers in the network
    layersNames = net.getLayerNames()
    # Get the names of the output layers, i.e. the layers with unconnected outputs
    return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# Draw the predicted bounding box
def drawPred(frame, classId, conf, left, top, right, bottom):
    # Draw a bounding box.
    cv.rectangle(frame, (left, top), (right, bottom), (255, 178, 50), 3)

    label = '%.2f' % conf

    # Get the label for the class name and its confidence
    if classes:
        assert(classId < len(classes))
        label = '%s:%s' % (classes[classId], label)

    #Display the label at the top of the bounding box
    labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1)
    top = max(top, labelSize[1])
    cv.rectangle(frame, (left, top - round(1.5*labelSize[1])), (left + round(1.5*labelSize[0]), top + baseLine), (255, 255, 255), cv.FILLED)
    cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0,0,0), 1)

# Remove the bounding boxes with low confidence using non-maxima suppression
def postprocess(frame, outs):
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]

    # Scan through all the bounding boxes output from the network and keep only the
    # ones with high confidence scores. Assign the box's class label as the class with the highest score.
    classIds = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            classId = np.argmax(scores)
            confidence = scores[classId]
            if confidence > confThreshold:
                center_x = int(detection[0] * frameWidth)
                center_y = int(detection[1] * frameHeight)
                width = int(detection[2] * frameWidth)
                height = int(detection[3] * frameHeight)
                left = int(center_x - width / 2)
                top = int(center_y - height / 2)
                classIds.append(classId)
                confidences.append(float(confidence))
                boxes.append([left, top, width, height])

    # Perform non maximum suppression to eliminate redundant overlapping boxes with
    # lower confidences.
    indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
    person_count = 0
    for i in indices:
        i = i[0]
        if classes[classIds[i]] == "person":
            person_count += 1
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        drawPred(frame, classIds[i], confidences[i], left, top, left + width, top + height)

    return person_count


def show_in_window(frame):
    winName = 'Deep learning object detection in OpenCV'
    cv.namedWindow(winName, cv.WINDOW_NORMAL)
    cv.imshow(winName, frame)

    while 1:
        c = cv.waitKey(0)
        if c == 27:
            break

def detect_from_image(image_filename):
    # Open the image file

    print("Opening file: " + image_filename)

    cap = cv.VideoCapture(image_filename)

    print("File opened.")

    hasFrame, frame = cap.read()
    frame = imutils.resize(frame, width=inpWidth)
    (h, w) = frame.shape[:2]

    print("Step 1.")

    # Create a 4D blob from a frame.
    blob = cv.dnn.blobFromImage(cv.resize(frame, (inpWidth, inpHeight)), 0.007843, (inpWidth, inpHeight), 127.5)

    print("Step 2.")

    # Sets the input to the network
    net.setInput(blob)

    print("Step 3.")

    # Runs the forward pass to get output of the output layers
    outputsNames = getOutputsNames(net)
    outs = net.forward(outputsNames)

    print("Step 4.")

    # Remove the bounding boxes with low confidence
    person_count = postprocess(frame, outs)

    print("Done processing object detection !!!")
    # Release device
    cap.release()

    show_in_window(frame)

    return person_count

I make a call to detect_from_image() with the image's filename as a parameter. The program runs but never makes it to the "step 4" print, so it probably crashes at the net.forward() call.

Does anyone have any ideas what might be causing this and how it can be resolved? Could it be that the Pi has insufficient memory? (it only has 1 GB RAM...)

Note that the script runs fine on my laptop and I know it's not a power issue, as there's no such message in the system logs.

I got the code above and the pre-trained network from here. Also, I don't think it matters but I am using ssh to connect to the raspberry pi.

Thanks in advance for any help.

  • 1
    Increase the swap size if you suspect you're running out of RAM. – Dmitry Grigoryev Jan 27 at 9:26
  • 1
    Don't guess where it crashes, find out. Put additional prints in the script to find the exact place. If it is in another scripts add prints to that. Also print the parameters being passed at the point of failure, perhaps they are wrong. – joan Jan 27 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.