简体   繁体   中英

If a car is recognized take a picture

Run this code for Python and OpenCv. What i want to do, is to save in my dataset/test all the images of all the cars that the tool is detecting. Run my code with

python3 car_detection y0d$ python3 build_car_dataset.py -c cars.xml -o dataset/test

So when i detect the face and put the rectangle on the face, i created an if function that is saying that if the face is recognized and has the rectangle on the image, then please save the pic of that face to my desired output

if rects:
            p = os.path.sep.join([args["output"], "{}.png".format(str(total).zfill(5))])
            cv2.imwrite(p, orig)
            total += 1

So the error i got is: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() What should i do? Thank you in advance!

My full code is:

# USAGE
# python3 build_car_dataset.py --cascade haarcascade_frontalface_default.xml --output dataset/test
#  python3 build_face_dataset.py -c haarcascade_licence_plate_rus_16stages_original.xml -o dataset/test
#python3 build_face_dataset.py -c haarcascade_licence_plate_rus_16stages_original.xml -o dataset/test
#python3 build_car_dataset.py -c cars.xml -o dataset/test
from imutils.video import VideoStream
import argparse, imutils, time, cv2, os

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--cascade", required=True,
    help = "path to where the face cascade resides")
ap.add_argument("-o", "--output", required=True,
    help="path to output directory")
args = vars(ap.parse_args())

# load OpenCV's Haar cascade for face detection from disk
detector = cv2.CascadeClassifier(args["cascade"])

# initialize the video stream, allow the camera sensor to warm up and initialize the total number of example faces written to disk  thus far
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
# vs = VideoStream(usePiCamera=True).start()
time.sleep(2.0)
total = 0
# loop over the frames from the video stream
while True:
    # grab the frame from the threaded video stream, clone it, (just in case we want to write it to disk), and then resize the frame
    # so we can apply face detection faster
    frame = vs.read()
    orig = frame.copy()
    frame = imutils.resize(frame, width=400)
    # detect faces in the grayscale frame
    rects = detector.detectMultiScale(
        cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), scaleFactor=1.1, 
        minNeighbors=5, minSize=(30, 30))
    # loop over the face detections and draw them on the frame
    for (x, y, w, h) in rects:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        if rects:
            p = os.path.sep.join([args["output"], "{}.png".format(str(total).zfill(5))])
            cv2.imwrite(p, orig)
            total += 1

    # show the output frame
    cv2.imshow("Frame", frame)

    key = cv2.waitKey(1) & 0xFF 


    # if the `q` key was pressed, break from the loop
    if key == ord("q"):
        break
# do a bit of cleanup
print("[INFO] {} face images stored".format(total))
print("[INFO] cleaning up...")
cv2.destroyAllWindows()
vs.stop()

Replace:

if rects:

with:

if rects is not None :

or with:

if rects != None :

and you'll be golden =)

I mean, you still won't be able to detect cars, but at least the error will go away. For the car detection I'd recommend to use CNN (convolution neural networks), google for "YOLO CNN" or "SSD CNN" -- there are plenty of already existing projects that detect cars, you may easily give yourself a good head start.

Let's say rects = [[1, 2, 3, 4], [3,4, 5, 6]]

for (x, y, w, h) in rects:
    print("I got here:", x, y, w, h)

would print:

I got here: 1 2 3 4
I got here: 3 4 5 6

But if rects = None , you'd get the error, 'NoneType' object is not iterable If rects = [] you get no output and nothing inside the loop runs.

Basically what I'm saying is that because your if rects code is inside a loop that is looping through rects , you are already guaranteed that rects has info in it since your code needed rects to be a non-empty iterable to get that far.

What you probably really want to do is check if rects prior to looping over it. To be pythonic, we'll ask forgiveness rather than permission:

rects = None
try:
    for (x, y, w, h) in rects:
        print("I got here:", x, y, w, h)
except TypeError:
    print("no rects")

# no rects

Note that your error has little to do with the majority of your code. Be sure to try to reduce your problem to the smallest possible reproducible example that has the same issue. Often by doing so, it helps solve the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM