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","."]
docstr: Read all the records out of the CSV file.
  
  If they've been previously read, just return the records.
  
  Returns:
      Dictionary mapping `image_id`s to a list of annotations.
docstr_tok: ["Read","all","the","records","out","of","the","CSV","file",".","If","they","'ve","been","previously","read",",","just","return","the","records",".","Returns",":","Dictionary","mapping","`","image_id","`","s","to","a","list","of","annotations","."]
code: def _get_records(self):
      """Read all the records out of the CSV file.
  
      If they've been previously read, just return the records.
  
      Returns:
          Dictionary mapping `image_id`s to a list of annotations.
      """
      if self._records is None:
          with tf.gfile.Open(self._annotations_path) as annotations:
              if self._has_headers:
                  reader = csv.DictReader(annotations)
              else:
                  # If file has no headers, pass the field names to the CSV
                  # reader.
                  reader = csv.DictReader(
                      annotations, fieldnames=self._columns
                  )
  
          images_gt_boxes = {}
  
          for row in reader:
              # When reading the first row, make sure the CSV is correct.
              self._check_csv(row)
  
              # Then proceed as normal, reading each row and aggregating
              # bounding boxes by image.
              label = self._normalize_row(row)
              image_id = label.pop("image_id")
              images_gt_boxes.setdefault(image_id, []).append(label)
  
          self._records = images_gt_boxes
  
      return self._records
  
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 5 for calling the CSVReader obj's underlying member method code with example usage: obj._get_records() and returns: self