numpy.ndarray object has no attribute 'read'(and 'seek')

Question:

I am getting the error numpy.ndarray object has no attribute 'read' and numpy.ndarray object has no attribute 'seek'. I tried looking for the answer online but I failed.

What I am trying to do is detect objects in a video – in this case I want to detect zebras.

I took an image detector and I am trying to apply it to video. I am trying to loop over each frame of the video and ultimately passing the frame to the function draw_boxes.

Here is the error message:

Traceback (most recent call last):
  File "/Users/ysquared/Library/Python/3.7/lib/python/site-packages/PIL/Image.py", line 2770, in open
    fp.seek(0)
AttributeError: 'numpy.ndarray' object has no attribute 'seek'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 204, in <module>
  File "<string>", line 118, in load_image_pixels
  File "/Users/ysquared/Library/Python/3.7/lib/python/site-packages/keras_preprocessing/image/utils.py", line 110, in load_img
    img = pil_image.open(path)
  File "/Users/ysquared/Library/Python/3.7/lib/python/site-packages/PIL/Image.py", line 2772, in open
    fp = io.BytesIO(fp.read())
AttributeError: 'numpy.ndarray' object has no attribute 'read'

And here is the relevant code:

model = load_model('model.h5')

# define the expected input shape for the model
input_w, input_h = 416, 416

# define the anchors
anchors = [[116,90, 156,198, 373,326], [30,61, 62,45, 59,119], [10,13, 16,30, 33,23]]

# define the labels
labels = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck",
        "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench",
        "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe",
        "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard",
        "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
        "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana",
        "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake",
        "chair", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop", "mouse",
        "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator",
        "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"]

vs = cv2.VideoCapture('Zebras.mp4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
writer = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

class_threshold = 0.6
boxes = list()

while True:
    (grabbed, frame) = vs.read()

    if grabbed==True:

        image, image_w, image_h = load_image_pixels(frame, (input_w, input_h))
        yhat = model.predict(image)

        for i in range(len(yhat)):
            # decode the output of the network
            boxes += decode_netout(yhat[i][0], anchors[i], class_threshhold, input_h, input_w)
         # correct the sizes of the bounding boxes for the shape of the image
        correct_yolo_boxes(boxes, image_h, image_w, input_h, input_w)
         # suppress non-maximal boxes
        do_nms(boxes, 0.5)

         # get the details of the detected objects
        v_boxes, v_labels, v_scores = get_boxes(boxes, labels, class_threshold)

         # draw what we found
        frame = draw_boxes(frame, v_boxes, v_labels, v_scores)

        writer.write(frame)

        cv2.imshow('frame', frame)

        if cv2.waitkey(1) & 0xFF == ord('q'):
            break

    else:
        break

vs.release()

writer.release()

cv2.destroyAllWindows()

Asked By: ysquared

||

Answers:

seek and read are things that an opened file can do. I deduce from the traceback that this error occurs in the

image, image_w, image_h = load_image_pixels(frame, (input_w, input_h))

line, and the problem must be in the frame argument. That function expects an opened file or filename, but frame apparently is numpy array. It is defined above in:

(grabbed, frame) = vs.read()

So it’s a frame from the mp4, an array, not a file.

So either you need to give load_image_pixels a file name, or you need to use some other function to process the frame array.

A general web search doesn’t help with this kind of error. It is both too broad and too specific.

no attribute errors in Python are common. It means the object at that point has a different class than what the programmer intended. For example if a cv read can’t find the file, it returns a None, instead of an image. You can’t process None as though it were an image. But your particular combination of using an array instead of a filename is unique.

Before doing a web search, try to understand where the error occurs, and what variable(s) is involved. Check both it’s actual nature (type, shape, etc) and the expectations of the code, the function(s) being called.

Answered By: hpaulj

Here is how I solved the problem(i.e got rid of the error):


##[..] 
cv2.imwrite("framex.jpg", frame)
filename = "framex.jpg"

image, image_w, image_h = load_image_pixels(filename, (input_w, input_h))

##[..]

frame = draw_boxes(filename, v_boxes, v_labels, v_scores)

##[..]
Answered By: ysquared

I got this same error because of this line of code

image = Image.open(frame).convert("RGB")

I solved it by switching that line for this line

image = Image.fromarray(frame)
Answered By: user8214