class_docstr: CSVReader supports reading annotations out of a CSV file.
  
  The reader requires the following directory structure within `data_dir`:
  * Annotation data (bounding boxes) per split, under the name `{split}.csv`
    on the root directory.
  * Dataset images per split, under the `{split}/` directory on the root
    directory.
  
  Thus, a CSV dataset directory structure may look as follows::
  
      .
      ├── train
      │   ├── image_1.jpg
      │   ├── image_2.jpg
      │   └── image_3.jpg
      ├── val
      │   ├── image_4.jpg
      │   ├── image_5.jpg
      │   └── image_6.jpg
      ├── train.csv
      └── val.csv
  
  The CSV file itself must have the following format::
  
      image_id,xmin,ymin,xmax,ymax,label
      image_1.jpg,26,594,86,617,cat
      image_1.jpg,599,528,612,541,car
      image_2.jpg,393,477,430,552,dog
  
  You can skip the header by overriding the `headers` parameter, in which
  case the `columns` option will be used (specified as either a string or a
  comma-separated list of fields). If this is done, the above six columns
  *must* be present. Extra columns will be ignored.
class_docstr_tok: ["CSVReader","supports","reading","annotations","out","of","a","CSV","file",".","The","reader","requires","the","following","directory","structure","within","`","data_dir","`",":","*","Annotation","data","(","bounding","boxes",")","per","split",",","under","the","name","`","{","split","}",".csv","`","on","the","root","directory",".","*","Dataset","images","per","split",",","under","the","`","{","split","}","\/","`","directory","on","the","root","directory",".","Thus",",","a","CSV","dataset","directory","structure","may","look","as","follows",":",":",".","\u251c\u2500\u2500","train","\u2502","\u251c\u2500\u2500","image_1.jpg","\u2502","\u251c\u2500\u2500","image_2.jpg","\u2502","\u2514\u2500\u2500","image_3.jpg","\u251c\u2500\u2500","val","\u2502","\u251c\u2500\u2500","image_4.jpg","\u2502","\u251c\u2500\u2500","image_5.jpg","\u2502","\u2514\u2500\u2500","image_6.jpg","\u251c\u2500\u2500","train.csv","\u2514\u2500\u2500","val.csv","The","CSV","file","itself","must","have","the","following","format",":",":","image_id",",","xmin",",","ymin",",","xmax",",","ymax",",","label","image_1.jpg,26,594,86,617",",","cat","image_1.jpg,599,528,612,541",",","car","image_2.jpg,393,477,430,552",",","dog","You","can","skip","the","header","by","overriding","the","`","headers","`","parameter",",","in","which","case","the","`","columns","`","option","will","be","used","(","specified","as","either","a","string","or","a","comma-separated","list","of","fields",")",".","If","this","is","done",",","the","above","six","columns","*","must","*","be","present",".","Extra","columns","will","be","ignored","."]
code: def iterate(self):
      records = self._get_records()
      for image_id, annotations in records.items():
          if self._stop_iteration():
              return
  
          if self._should_skip(image_id):
              continue
  
          image_path = os.path.join(self._images_dir, image_id)
          try:
              image = read_image(image_path)
          except tf.errors.NotFoundError:
              tf.logging.warning(
                  "Image `{}` at `{}` couldn't be opened.".format(
                      image_id, image_path
                  )
              )
              self.errors += 1
              continue
  
          image_pil = Image.open(six.BytesIO(image))
          width = image_pil.width
          height = image_pil.height
  
          gt_boxes = []
          for annotation in annotations:
              try:
                  label_id = self.classes.index(annotation["label"])
              except ValueError:
                  tf.logging.warning(
                      "Error finding id for image `{}`, label `{}`.".format(
                          image_id, annotation["label"]
                      )
                  )
                  continue
  
              gt_boxes.append(
                  {
                      "label": label_id,
                      "xmin": annotation["xmin"],
                      "ymin": annotation["ymin"],
                      "xmax": annotation["xmax"],
                      "ymax": annotation["ymax"],
                  }
              )
  
          if len(gt_boxes) == 0:
              continue
  
          record = {
              "width": width,
              "height": height,
              "depth": 3,
              "filename": image_id,
              "image_raw": image,
              "gt_boxes": gt_boxes,
          }
          self._will_add_record(record)
          self.yielded_records += 1
  
          yield record
  
file_path: luminoth/luminoth/tools/dataset/readers/object_detection/csv_reader.py
imports: import csv
  import os
  import six
  import tensorflow
  from PIL import Image
  from luminoth.tools.dataset.readers import InvalidDataDirectory
  from luminoth.tools.dataset.readers.object_detection import ObjectDetectionReader
  from luminoth.utils.config import is_basestring
  from luminoth.utils.dataset import read_image
label_desc: Use image node_id 4 for calling the CSVReader obj's underlying member method code with example usage: obj.iterate() without return types