title: How to export TensorFlow object detection labels and bounding boxes as CSV file?
body: <p>I'm working on an object detection model to aid in inspection. One feature is that if it finds an error in the input video, it will raise a notification and export the data to CSV. I'd like it to export the label and bounding box coordinates of the error, along with the timestamp and frame count if possible.</p>
  
  <p>I've seen <a href="https://stackoverflow.com/questions/48343678/store-tensorflow-object-detection-api-image-output-with-boxes-in-csv-format">one answer</a> about exporting bounding boxes to CSV but it hasn't worked yet, and gives me the error</p>
  
  <p><code>File "C:\Users\Charles.averill\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\npyio.py", line 1377, in savetxt
      "Expected 1D or 2D array, got %dD array instead" % X.ndim)
  ValueError: Expected 1D or 2D array, got 3D array instead</code></p>
  
  <p>I have it so that the video is annotating, and once it's finished, it prompts the user to export to CSV or not, so I have another method for the exporting. Here's my code:</p>
  
  <pre><code>def annotate(self):
      if("annotated" in self.video_path):
          messagebox.showinfo("Error", "You can't annotate an annotated video!")
      elif(self.mode == "V" and not self.video_path is None):
          fourcc = cv2.VideoWriter_fourcc(*'MP4V')
          time = datetime.datetime.now().strftime('%Y-%m-%d %H_%M_%S')
          path = 'output/videos/annotated_' + time + '_output.mp4'
          out = cv2.VideoWriter(path, fourcc, 20.0, (960, 540))
          self.rewind()
          NUM_CLASSES = 2
          detection_graph = tf.Graph()
          with detection_graph.as_default():
              od_graph_def = tf.compat.v1.GraphDef()
              with tf.io.gfile.GFile(self.model_graph, 'rb') as fid:
                  serialized_graph = fid.read()
                  od_graph_def.ParseFromString(serialized_graph)
                  tf.import_graph_def(od_graph_def, name='')
          lmap = label_map_util.load_labelmap(self.label_map)
          categories = label_map_util.convert_label_map_to_categories(lmap, max_num_classes=NUM_CLASSES, use_display_name=True)
          category_index = label_map_util.create_category_index(categories)
  
          with detection_graph.as_default():
              with tf.compat.v1.Session(graph=detection_graph) as sess:
                  while not self.currentFrame is None:
                      image_np = self.get_just_frame()
                      if(image_np is None):
                          break
                      image_np_expanded = np.expand_dims(image_np, axis=0)
  
                      image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
  
                      self.boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
  
                      self.scores = detection_graph.get_tensor_by_name('detection_scores:0')
  
                      classes = detection_graph.get_tensor_by_name('detection_classes:0')
  
                      num_detections = detection_graph.get_tensor_by_name(
                          'num_detections:0')
  
                      (self.boxes, self.scores, classes, num_detections) = sess.run(
                          [self.boxes, self.scores, classes, num_detections],
                          feed_dict={image_tensor: image_np_expanded})
  
                      vis_util.visualize_boxes_and_labels_on_image_array(
                          image_np,
                          np.squeeze(self.boxes),
                          np.squeeze(classes).astype(np.int32),
                          np.squeeze(self.scores),
                          category_index,
                          use_normalized_coordinates=True,
                          line_thickness=2)
  
                      # Display output
                      out.write(image_np)
          self.video.release()
          out.release()
          self.video = None
          self.set_video_path(path)
          self.video = cv2.VideoCapture(self.video_path)
          if(not self.video.isOpened()):
              raise ValueError("Unable to open video source", self.video_path)
          ret, frame = self.get_frame()
          if(ret and not frame is None):
              self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))  
              self.canvas.create_image(0, 0, image = self.photo, anchor = NW)
          MsgBox = tk.messagebox.askquestion ('Export to CSV','Do you want to export the video to CSV?',icon = 'warning')
          if MsgBox == 'yes':
             self.export_CSV()
      if(self.video_path is None):
          messagebox.showinfo("Error", "No video selected")
  
  def export_CSV(self):
      if(not self.boxes is None):
          print(self.boxes)
          for i, box in enumerate(np.squeeze(self.boxes)):
              if(np.squeeze(self.scores)[i] &gt; 0.5):
                  print("ymin={}, xmin={}, ymax={}, xmax{}".format(box[0]*540,box[1]*960,box[2]*540,box[3]*960))
          time = datetime.datetime.now().strftime('%Y-%m-%d %H_%M_%S')
          path = 'output/csv/' + time + '_output.csv'
          np.savetxt(path, self.boxes, delimiter=',')
      else:
          messagebox.showinfo("Error", "No boxes, you must\nannotate the video first")
  </code></pre>
  
  <p>How could I export the labels along with the bounding boxes?</p>
  
  <p>Thank you!</p>