-2

I came across a problem: the code works so that when a car passes the camera, a video of its passage is saved, then the function starts again through recursion, but exactly at 4th cycle the code gives an error

    (H, W) = image.shape[:2]

AttributeError: 'NoneType' object has no attribute 'shape'

Here is the code itself:

   import cv2 as cv
import numpy as np
import uuid
import os.path
import os
def camera():
    print("new cycle")
    confThreshold = 0.6
    nmsThreshold = 0.1
    inpWidth = 416
    inpHeight = 416
    classesFile = "car.names"
    classes = None
    with open(classesFile, 'rt') as f:
        classes = f.read().rstrip('\n').split('\n')
    modelConf = "car.cfg"
    modelWeights = "cars_last.weights"
    cap = cv.VideoCapture("rtsp://.../user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream:")
    ret, image = cap.read()
    (H, W) = image.shape[:2]
    global empty
    global newname
    newname = str(uuid.uuid4())
    global output
    output = cv.VideoWriter(newname+'.avi', cv.VideoWriter_fourcc('M','J','P','G'), 10,
                            (W, H))
    print(newname)
    empty = []
    def postprocess(frame, outs):
        frameHeight = frame.shape[0]
        frameWidth = frame.shape[1]

        classIDs = []
        confidences = []
        boxes = []
        boxes1=[]
        cv.cvtColor(frame, cv.COLOR_RGB2BGR)

        for out in outs:
            for detection in out:

                scores = detection[5:]
                classID = np.argmax(scores)
                confidence = scores[classID]

                if confidence > confThreshold:
                    centerX = int(detection[0] * frameWidth)
                    centerY = int(detection[1] * frameHeight)

                    width = int(detection[2] * frameWidth)
                    height = int(detection[3] * frameHeight)

                    left = int(centerX - width / 2)
                    top = int(centerY - height / 2)
                    x = int(centerX - (width / 2))
                    y = int(centerY - (height / 2))
                    boxes1.append([x, y, int(width), int(height)])
                    classIDs.append(classID)
                    confidences.append(float(confidence))
                    boxes.append([left, top, width, height])
        idxs = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
        if len(idxs) > 0:
            empty.clear()
            empty.append(0)
        else:
            empty.append(1)
        if len(empty)>100:
            empty.clear()
            if (os.path.isfile(newname+".avi"))==True and os.path.getsize(newname+".avi")!=0:
                camera()


        indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
        for i in indices:
            i = i[0]
            box = boxes[i]
            left = box[0]
            top = box[1]
            width = box[2]
            height = box[3]

            drawPred(classIDs[i], confidences[i], left, top, left + width, top + height)
            output.write(frame)


    def drawPred(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)

        
        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.rectangle(frame, (left,top),(right,bottom), (255,255,255), 1 )
        cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 0), 1)



    def getOutputsNames(net):
        layersNames = net.getLayerNames()

        return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]

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

    winName = 'DL OD with OpenCV'
    cv.namedWindow(winName, cv.WINDOW_NORMAL)



    while cv.waitKey(1) < 0:

        hasFrame, frame = cap.read()

        blob = cv.dnn.blobFromImage(frame, 1 / 255, (inpWidth, inpHeight), [0, 0, 0], 1, crop=False)

        net.setInput(blob)
        outs = net.forward(getOutputsNames(net))

        postprocess(frame, outs)

        cv.imshow(winName, frame)
    cap.release()
    output.release()
camera()
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Chingiz K
  • 26
  • 3

2 Answers2

0

As spotted in the doc about the read function :

Parameters [out] image the video frame is returned here. If no frames has been grabbed the image will be empty.

You should check the return status to know if you have image data.

Returns false if no frames has been grabbed

Ptit Xav
  • 3,006
  • 2
  • 6
  • 15
0

all i had to do is to put camera connection out of recursion, I have put it outside the camera func thx all for help)

    cap = cv.VideoCapture("rtsp:///user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream:")
ret, image = cap.read()
Chingiz K
  • 26
  • 3