class_docstr: ObjectDetection dataset as DataFrame.
  
  Parameters
  ----------
  data : the input for pd.DataFrame
      The input data.
  dataset_type : str, optional
      The dataset type, can be voc/coco or more, used to annotate the optional fields.
  classes : list of str, optional
      The class synsets for this dataset, if `None`, it will infer from the data.
class_docstr_tok: ["ObjectDetection","dataset","as","DataFrame",".","Parameters","--","--","--","--","--","data",":","the","input","for","pd.DataFrame","The","input","data",".","dataset_type",":","str",",","optional","The","dataset","type",",","can","be","voc\/coco","or","more",",","used","to","annotate","the","optional","fields",".","classes",":","list","of","str",",","optional","The","class","synsets","for","this","dataset",",","if","`","None","`",",","it","will","infer","from","the","data","."]
docstr: construct from pascal VOC format.
  Normally you will see a structure like:
  
  ├── VOC2007
  │   ├── Annotations
  │   ├── ImageSets
  |   |   ├── Main
  |   |   |   ├── train.txt
  |   |   |   ├── test.txt
  │   ├── JPEGImages
  
  Parameters
  ----------
  root : str or url
      The root directory for VOC, e.g., the `VOC2007`. If an url is provided, it will be downloaded and extracted.
  splits : tuple of str, optional
      If given, will search for this name in `ImageSets/Main/`, e.g., ('train', 'test')
  exts : tuple of str, optional
      The supported image formats.
code: def from_voc(cls, root, splits=None, exts=(".jpg", ".jpeg", ".png")):
      """construct from pascal VOC format.
      Normally you will see a structure like:
  
      ├── VOC2007
      │   ├── Annotations
      │   ├── ImageSets
      |   |   ├── Main
      |   |   |   ├── train.txt
      |   |   |   ├── test.txt
      │   ├── JPEGImages
  
      Parameters
      ----------
      root : str or url
          The root directory for VOC, e.g., the `VOC2007`. If an url is provided, it will be downloaded and extracted.
      splits : tuple of str, optional
          If given, will search for this name in `ImageSets/Main/`, e.g., ('train', 'test')
      exts : tuple of str, optional
          The supported image formats.
  
      """
      if is_url(root):
          root = url_data(root)
      rpath = Path(root).expanduser()
      img_list = []
      class_names = set()
      if splits:
          logger.debug("Use splits: %s for root: %s", str(splits), root)
          if isinstance(splits, str):
              splits = [splits]
          for split in splits:
              split_file = rpath / "ImageSets" / "Main" / split
              if not split_file.resolve().exists():
                  split_file = (
                      rpath / "ImageSets" / "Main" / (split + ".txt")
                  )
              if not split_file.resolve().exists():
                  raise FileNotFoundError(split_file)
              with split_file.open(mode="r") as fi:
                  img_list += [
                      line.split()[0].strip() for line in fi.readlines()
                  ]
      else:
          logger.debug(
              "No split provided, use full image list in %s, with extension %s",
              str(rpath / "JPEGImages"),
              str(exts),
          )
          if not isinstance(exts, (list, tuple)):
              exts = [exts]
          for ext in exts:
              img_list.extend(
                  [rp.stem for rp in rpath.glob("JPEGImages/*" + ext)]
              )
      d = {"image": [], "rois": [], "image_attr": []}
      for stem in img_list:
          basename = stem + ".xml"
          anno_file = (rpath / "Annotations" / basename).resolve()
          tree = ET.parse(anno_file)
          xml_root = tree.getroot()
          size = xml_root.find("size")
          im_path = xml_root.find("filename").text
          width = float(size.find("width").text)
          height = float(size.find("height").text)
          rois = []
          for obj in xml_root.iter("object"):
              try:
                  difficult = int(obj.find("difficult").text)
              except ValueError:
                  difficult = 0
              cls_name = obj.find("name").text.strip().lower()
              xml_box = obj.find("bndbox")
              xmin = (
                  max(0, float(xml_box.find("xmin").text) - 1) / width
              )
              ymin = (
                  max(0, float(xml_box.find("ymin").text) - 1) / height
              )
              xmax = (
                  min(width, float(xml_box.find("xmax").text) - 1)
                  / width
              )
              ymax = (
                  min(height, float(xml_box.find("ymax").text) - 1)
                  / height
              )
              if xmin >= xmax or ymin >= ymax:
                  logger.warning(
                      "Invalid bbox: {%s} for {%s}",
                      str(xml_box),
                      anno_file.name,
                  )
              else:
                  rois.append(
                      {
                          "class": cls_name,
                          "xmin": xmin,
                          "ymin": ymin,
                          "xmax": xmax,
                          "ymax": ymax,
                          "difficult": difficult,
                      }
                  )
                  class_names.update((cls_name,))
          if rois:
              d["image"].append(str(rpath / "JPEGImages" / im_path))
              d["rois"].append(rois)
              d["image_attr"].append({"width": width, "height": height})
      df = pd.DataFrame(d)
      return cls(
          df.sort_values("image").reset_index(drop=True),
          dataset_type="voc",
          classes=list(class_names),
      )
  
imports: import logging
  import os
  from pathlib import Path
  import warnings
  import numpy
  import pandas
  import matplotlib.pyplot
  from PIL import Image
  import cv2
  from ..data import is_url, url_data
  from ...utils.filesystem import import_try_install
  from ...utils.bbox import bbox_xywh_to_xyxy, bbox_clip_xyxy
label_desc: Use image node_id 4 for calling the ObjectDetectionDataset obj's underlying member method code with example usage: obj.from_voc(cls, root, splits, exts) and returns: cls