docstr: :param chips:
  :param pos_chip_ids:
  :param proposals:
  :return: neg_chip2box_num, None or dict: chipid->neg_box_num
docstr_tok: [":","param","chips",":",":","param","pos_chip_ids",":",":","param","proposals",":",":","return",":","neg_chip2box_num",",","None","or","dict",":","chipid-",">","neg_box_num"]
code: def _get_neg_boxes_and_chips(
      self, chips: "Cx4", pos_chip_ids: "D", proposals: "Px4"
  ):
      """
      :param chips:
      :param pos_chip_ids:
      :param proposals:
      :return: neg_chip2box_num, None or dict: chipid->neg_box_num
      """
      if not self.use_neg_chip:
          return None
  
      # train proposals maybe None
      if proposals is None or len(proposals) < 1:
          return None
  
      valid_ratio_range = self._cur_valid_ratio_range
      im_size = self._cur_im_size
      scale = self._cur_scale
  
      valid_props, _ = self._validate_boxes(
          valid_ratio_range, im_size, proposals, scale
      )
      neg_boxes = self._find_neg_boxes(chips, pos_chip_ids, valid_props)
      neg_chip2box_num = self._find_neg_chips(
          chips, pos_chip_ids, neg_boxes
      )
      return neg_chip2box_num
  
imports: import copy
  import math
  import random
  import numpy
  from copy import deepcopy
  from typing import List, Tuple
  from collections import defaultdict
  from .chip_box_utils import nms, transform_chip_boxes2image_boxes
  from .chip_box_utils import find_chips_to_cover_overlaped_boxes
  from .chip_box_utils import transform_chip_box
  from .chip_box_utils import intersection_over_box
label_desc: Use image node_id 16 for calling the AnnoCropper obj's underlying member method code with example usage: obj._get_neg_boxes_and_chips(chips, pos_chip_ids, proposals) and returns: neg_chip2box_num, None, None