Home > Mobile >  How to solve Python webcam crash. I'm using webcam to count the number of Person/Car/Truck that
How to solve Python webcam crash. I'm using webcam to count the number of Person/Car/Truck that

Time:05-31

I want to make a Person/Car/Truck count program using Python and Pycharm using webcam.

The video source is from a webcam (private link).

When the 'Person' button (on the left side) is clicked, from that moment, everytime a person walk accross the red line (green line is the starting parameter), the program will count it as 1 person and continue counting until the same Person' button (on the left side) is clicked. Same goes for 'Car' button and 'Truck' button. The total count for Car and Truck is also shown at the window.

I already have a working code for to do this but whenever I run the program (py file), for unknown reason, it will crash/stop few moments later around 15 seconds to 30 seconds from its start. The error is:

Traceback (most recent call last):
  File "C:/Users/admin/Desktop/Fadhli/License Plate Recognition/Mark1/mark5_1.py", line 110, in <module>
    frame = frame2.copy()
AttributeError: 'NoneType' object has no attribute 'copy'

Process finished with exit code 1

I tested the same code but I change the coding to use my own webcam and it works fine and didn't crash.

I suspect the problem is because there's some filter from the private webcam or something that causes the program to stuck and then crash.

My question is, how do I either:

A) add buffer or something like that, so that the program doesn't hang or

B) altogether bypass the filter from that private camera so that

the program doesn't crash.

My coding:

import cv2
import numpy as np

# Resolution Pixel Size
# 640 x 480 - Standard Definition(SD)
# 1280 x 720 - High Definition(HD)
# 1920 x 1080 - Ultra High Definiion(HD )
# 3840 x 2160 - Ultra High Definition(UHD or 2K)

cyanColor = (255, 255, 0)
pinkColor = (255, 0, 255)
yellowColor = (0, 255, 255)
greenColor = (0, 255, 0)
blueColor = (255, 0, 0)
redColor = (0,0,255)

path_vid = "Resources/video/license_plate.mp4"
path_main_ent= 'rtsp://admin:~~~Streaming/Channels/101'
path_parking_Lot = 'rtsp://admin:~~~/Streaming/Channels/101'

button_person = False
button_car = False
button_truck = False

counter = 0
nmsThreshold = 0.3
confThreshold = 0.4

def rescale_frame(image, percentage):
    width = int(image.shape[1] * percentage / 100)
    height = int(image.shape[0] * percentage / 100)
    new_frame = (width, height)
    return cv2.resize(image, new_frame, interpolation=cv2.INTER_AREA)

def click_button(event,x,y,flags,params):
    global button_person
    global button_car
    global button_truck

    if event == cv2.EVENT_LBUTTONDOWN:
        print(x,y)

        #   ------  Person Button Clicking  ---------
        polygon_person = np.array([[(20, 160), (200, 160), (200, 230), (20, 230)]])
        is_inside_person_button = cv2.pointPolygonTest(polygon_person,(x,y),False)
        if is_inside_person_button>0:
            print("You've clicked a button",x,y)

            if button_person is False:
                button_person = True
            else:
                button_person = False

            print("Now Person Button is: ",button_person)

        #   ------  Car Button Clicking  ---------
        polygon_car = np.array([[(20, 250), (200, 250), (200, 320), (20, 320)]])
        is_inside_car_button = cv2.pointPolygonTest(polygon_car, (x, y), False)
        if is_inside_car_button > 0:
            print("You've clicked a button", x, y)

            if button_car is False:
                button_car = True
            else:
                button_car = False

            print("Now Car Button is: ", button_car)

        #   ------  Truck Button Clicking  ---------
        polygon_truck = np.array([[(20, 340), (200, 340), (200, 410), (20, 410)]])
        is_inside_truck_button = cv2.pointPolygonTest(polygon_truck, (x, y), False)
        if is_inside_truck_button > 0:
            print("You've clicked a button", x, y)

            if button_truck is False:
                button_truck = True
            else:
                button_truck = False

            print("Now Truck Button is: ", button_truck)

# net = cv2.dnn.readNet("dnn_model/yolov3.weights", "dnn_model/yolov3.cfg")
# net = cv2.dnn.readNet("dnn_model/yolov3-spp.weights", "dnn_model/yolov3-spp.cfg")
# net = cv2.dnn.readNet("dnn_model/yolov3-tiny.weights", "dnn_model/yolov3-tiny.cfg")
# net = cv2.dnn.readNet("dnn_model/yolov4.weights", "dnn_model/yolov4.cfg")
net = cv2.dnn.readNet("dnn_model/yolov4-tiny.weights", "dnn_model/yolov4-tiny.cfg")

model = cv2.dnn_DetectionModel(net)
model.setInputParams(size=(640,480), scale=1/255)

classes = []
with open("dnn_model/classes.txt","r") as file_object:
    for class_name in file_object.readlines():
        class_name = class_name.strip()
        classes.append(class_name)

# print("- Object List -")
# print(classes[0])

cap = cv2.VideoCapture(path_main_ent)
# cap = cv2.VideoCapture(path_parking_Lot)

cv2.namedWindow("Frame")    # The name should be same with cv2.imshow("_Name_")
cv2.setMouseCallback("Frame",click_button)

ret,frame1 = cap.read()

while cap.isOpened():
    ret,frame2 = cap.read()
    frame = frame2.copy()
    # print(type(frame))
    if not ret:
        break

    img_frame_90 = rescale_frame(frame, 90)

    line_frame_above = cv2.line(img_frame_90, (390, 430), (1220, 470), yellowColor, 2)
    line_frame = cv2.line(img_frame_90, (380, 440), (1220, 480), blueColor, 4)
    line_frame_bottom = cv2.line(img_frame_90, (370, 450), (1220, 490), yellowColor, 2)

    polygon_person = np.array([[(20, 160), (200, 160), (200, 230), (20, 230)]])
    cv2.fillPoly(img_frame_90, polygon_person, greenColor)
    cv2.putText(img_frame_90, "Person", (50, 200), cv2.FONT_HERSHEY_PLAIN, 2, blueColor, 2)

    polygon_car = np.array([[(20, 250), (200, 250), (200, 320), (20, 320)]])
    cv2.fillPoly(img_frame_90, polygon_car, greenColor)
    cv2.putText(img_frame_90, "Car", (50, 290), cv2.FONT_HERSHEY_PLAIN, 2, blueColor, 2)

    polygon_truck = np.array([[(20, 340), (200, 340), (200, 410), (20, 410)]])
    cv2.fillPoly(img_frame_90, polygon_truck, greenColor)
    cv2.putText(img_frame_90, "Truck", (50, 380), cv2.FONT_HERSHEY_PLAIN, 2, blueColor, 2)

    (class_ids, scores, bboxes) = model.detect(img_frame_90,nmsThreshold=nmsThreshold, confThreshold=confThreshold)

    if len(class_ids) != 0:
        for class_id, score, bbox in zip(class_ids,scores,bboxes):
            (x,y,w,h) = bbox
            class_name = classes[class_id]
            xmid = int((x   (x   w)) / 2)
            ymid = int((y   (y   h)) / 2)

            if class_name == "person" and button_person is True:
                cv2.rectangle(img_frame_90, (x, y), (x   w, y   h), pinkColor, 2)
                cv2.circle(img_frame_90, (xmid, ymid), 3, redColor, -1)
                # cv2.putText(img_frame_90,str(class_name),(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,1,yellowColor,2)
                if ymid > 431 and ymid < 507 and xmid > 370 and xmid <490:
                    line_frame = cv2.line(img_frame_90, (350, 440), (1220, 480), greenColor, 4)
                    counter  = 1

            if class_name == "car" and button_car is True:
                cv2.rectangle(img_frame_90, (x, y), (x   w, y   h), greenColor, 2)
                cv2.circle(img_frame_90, (xmid, ymid), 3, redColor, -1)
                # cv2.putText(img_frame_90,str(class_name),(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,1,yellowColor,2)
                if ymid > 431 and ymid < 507:
                    line_frame = cv2.line(img_frame_90, (350, 440), (1220, 480), greenColor, 4)
                    counter  = 1

            if class_name == "truck" and button_truck is True:
                cv2.rectangle(img_frame_90, (x, y), (x   w, y   h), cyanColor, 2)
                cv2.circle(img_frame_90, (xmid, ymid), 3, redColor, -1)
                # cv2.putText(img_frame_90,str(class_name),(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,1,yellowColor,2)
                if ymid > 431 and ymid < 507:
                    line_frame = cv2.line(img_frame_90, (350, 440), (1220, 480), greenColor, 4)
                    counter  = 1

    cv2.putText(img_frame_90, 'Total Vehicles : {}'.format(counter), (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, yellowColor,2)

    frame1 = frame2

    cv2.imshow("Frame",img_frame_90)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

@KenY-N as per suggestion, I modified the code (from line 169) to

    cv2.putText(img_frame_90, 'Total Vehicles : {}'.format(counter), (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, yellowColor,2)

    frame1 = frame2
    if not frame2:
        continue

    cv2.imshow("Frame",img_frame_90)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

print(ret)

cap.release()
cv2.destroyAllWindows()

The result is still crash and error:

True
''
''
''
True
Traceback (most recent call last):
  File "C:/Users/admin/Desktop/Fadhli/License Plate Recognition/Mark1/mark5_1.py", line 172, in <module>
    if not frame2:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Process finished with exit code 1

CodePudding user response:

Here's the problem:

    ret,frame2 = cap.read()
    frame = frame2.copy()
    # print(type(frame))
    if not ret:
        break

This code tries to copy frame2 before checking whether the capture succeeded. Just rearrange the operations to put the check first:

    ret,frame2 = cap.read()
    # print(type(frame))
    if not ret:
        break
    frame = frame2.copy()

Of course break will break out of the loop on the first capture failure, so you might want to use continue instead.

CodePudding user response:

Try this solution for buffer issue. This uses the latest frame.

And to solve the error, try using:

ret,frame2 = cap.read()
if not ret:
    continue
  • Related