Search code examples
pythonnumpyobject-detectionvideo-processingobject-detection-api

numpy.ndarray has no attribute read (when trying to pass a video)


I am attempting to write a video with annotations to a file ( or at least print it our on-screen while using google colab). I've tried using cv_imshow but this prints the video one frame at a time, which is not what I'm after. I've amended the script to use VideoWriter, but still getting stuck when using cap.read() as I am getting an error stating numpy.ndarray has no attribute read.

I understand why this error is occurring, as I believe the .read() function is expecting a video, while I am trying to pass a numpy array. However, I cannot seem to find another way around this. any help would be highly appreciated.

This is the full code I am using:

import cv2
import tensorflow as tf
from google.colab.patches import cv2_imshow

cap = cv2.VideoCapture(r'/content/drive/MyDrive/vid1.mp4')
from google.colab.patches import cv2_imshow
import numpy as np


while True:
    ret, image_np = cap.read()

    image_np_expanded = np.expand_dims(image_np, axis=0)

    input_tensor = tf.convert_to_tensor(np.expand_dims(image_np, 0), dtype=tf.float32)
    detections, predictions_dict, shapes = detect_fn(input_tensor)

    label_id_offset = 1
    image_np_with_detections = image_np.copy()

    viz_utils.visualize_boxes_and_labels_on_image_array(
          image_np_with_detections,
          detections['detection_boxes'][0].numpy(),
          (detections['detection_classes'][0].numpy() + label_id_offset).astype(int),
          detections['detection_scores'][0
                                         ].numpy(),
          category_index,
          use_normalized_coordinates=True,
          max_boxes_to_draw=200,

          min_score_thresh=.30,
          agnostic_mode=False)

    cap=image_np_with_detections

    
  
    res=(800,600)              # this format fail to play in Chrome/Win10/Colab
              # fourcc = cv2.VideoWriter_fourcc(*'MP4V') #codec
    fourcc = cv2.VideoWriter_fourcc(*'H264') #codec
    out = cv2.VideoWriter('output.mp4', fourcc, 20.0, res)

    while(True):
    # Capture frame-by-frame
      ret, frame = cap.read()

      print("Frame number: " + str(counter))
      counter = counter+1
      if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    out.write(frame)

   

 out.release() 

 

cap.release()
cv2.destroyAllWindows()

Thanks in advance!


Solution

  • I managed to adjust the code in order to the VideoWriter to work. As hpaulj pointed out, I was assigning the variable cap twice.

    The correct code is below:

    cap = cv2.VideoCapture(r'/content/drive/MyDrive/Workspace/Images/Test/vid3.mp4')
    res=(800,600)            
    fourcc = cv2.VideoWriter_fourcc(*'H264') #codec
    out = cv2.VideoWriter('/content/drive/MyDrive/Workspace/Images/Test/vid3output.mp4', fourcc, 20.0, res)
    
      while True:
        ret, image_np = cap.read()
        ##expand dimensions as the model expects images to have the shape :: [1,None, None,3]
        image_np_expanded = np.expand_dims(image_np, axis=0)
    
        input_tensor = tf.convert_to_tensor(image_np_expanded, dtype=tf.float32)
        detections, predictions_dict, shapes = detect_fn(input_tensor)
    
        label_id_offset = 1
        image_np_with_detections = image_np.copy()
    
        viz_utils.visualize_boxes_and_labels_on_image_array(
              image_np_with_detections,
              detections['detection_boxes'][0].numpy(),
              (detections['detection_classes'][0].numpy() + label_id_offset).astype(int),
              detections['detection_scores'][0].numpy(),
              category_index,
              use_normalized_coordinates=True,
              max_boxes_to_draw=200,
              min_score_thresh=.5,
              agnostic_mode=False)
    
        out.write(cv2.resize(image_np_with_detections,(800,600)))
    
     
    # Release everything if job is finished
    cap.release()
    out.release()
    cv2.destroyAllWindows()