Ejemplo n.º 1
0
    def get2d_histogram(x, y, value_range, nbins=100, dtype=tf.dtypes.int32):
        """
        Bins x, y coordinates of points onto simple square 2d histogram
        Given the tensor x and y:
        x: x coordinates of points
        y: y coordinates of points
        this operation returns a rank 2 `Tensor`
        representing the indices of a histogram into which each element
        of `values` would be binned. The bins are equal width and
        determined by the arguments `value_range` and `nbins`.
      Args:
        x:  Numeric `Tensor`.
        y: Numeric `Tensor`.
        value_range[0] lims for x
        value_range[1] lims for y
        nbins:  Scalar `int32 Tensor`.  Number of histogram bins.
        dtype:  dtype for returned histogram.
        """
        x_range = value_range[0]
        y_range = value_range[1]

        histy_bins = tf.histogram_fixed_width_bins(y,
                                                   y_range,
                                                   nbins=nbins,
                                                   dtype=dtype)

        H = tf.map_fn(
            lambda i: tf.histogram_fixed_width(
                x[histy_bins == i], x_range, nbins=nbins), tf.range(nbins))
        return H  # Matrix!
Ejemplo n.º 2
0
  def scale_channel(im, c):
    """Scale the data in the channel to implement equalize."""
    im = tf.cast(im[:, :, c], tf.int32)
    # Compute the histogram of the image channel.
    histo = tf.histogram_fixed_width(im, [0, 255], nbins=256)

    # For the purposes of computing the step, filter out the nonzeros.
    nonzero = tf.where(tf.not_equal(histo, 0))
    nonzero_histo = tf.reshape(tf.gather(histo, nonzero), [-1])
    step = (tf.reduce_sum(nonzero_histo) - nonzero_histo[-1]) // 255

    def build_lut(histo, step):
      # Compute the cumulative sum, shifting by step // 2
      # and then normalization by step.
      lut = (tf.cumsum(histo) + (step // 2)) // step
      # Shift lut, prepending with 0.
      lut = tf.concat([[0], lut[:-1]], 0)
      # Clip the counts to be in range.  This is done
      # in the C code for image.point.
      return tf.clip_by_value(lut, 0, 255)

    # If step is zero, return the original image.  Otherwise, build
    # lut from the full histogram and step and then index from it.
    result = tf.cond(tf.equal(step, 0),
                     lambda: im,
                     lambda: tf.gather(build_lut(histo, step), im))

    return tf.cast(result, tf.uint8)
Ejemplo n.º 3
0
def tf_batch_histogram(values, value_range, axis, nbins=100, dtype=tf.int32, use_map=True):
    """
    Computes histogram with fixed width considering batch dimensions
    :param values: Numeric `Tensor` containing the values for histogram computation.
    :param value_range: Shape [2] `Tensor` of same `dtype` as `values`. values <= value_range[0] will be mapped to
    hist[0], values >= value_range[1] will be mapped to hist[-1].
    :param axis: Number of batch dimensions. First axis to apply histogram computation to.
    :param nbins: Scalar `int32 Tensor`. Number of histogram bins.
    :param dtype: dtype for returned histogram, can be either tf.int32 or tf.int64.
    :return: histogram with batch dimensions.
    """

    # Get shape
    values_shape = tf.shape(values)
    batch_dim = values_shape[:axis]
    rest_dim = values_shape[axis:]
    num_batch = tf.reduce_prod(batch_dim)

    if use_map:
        values_reshaped = tf.reshape(values, tf.concat([[num_batch], rest_dim], 0))
        hist = tf.map_fn(lambda x: tf.histogram_fixed_width(x, value_range, nbins=nbins, dtype=dtype), values_reshaped,
                         dtype=dtype, parallel_iterations=64)
    else:
        # Normalize
        values_float = tf.cast(values, tf.float32)
        value_range_float = tf.cast(value_range, tf.float32)

        # Clip values
        values_norm = (values_float - value_range_float[0]) / (value_range_float[1] - value_range_float[0])
        values_clip1 = tf.maximum(values_norm, 0.5 / tf.cast(nbins, tf.float32))
        values_clip2 = tf.minimum(values_clip1, 1.0 - 0.5 / tf.cast(nbins, tf.float32))

        # Shift values
        values_shift = values_clip2 + tf.reshape(tf.range(tf.cast(num_batch, tf.float32), dtype=tf.float32),
                                                 tf.concat([batch_dim, tf.ones(tf.size(rest_dim), tf.int32)], 0))

        # Get histogram
        hist = tf.histogram_fixed_width(values_shift, [0., tf.cast(num_batch, tf.float32)], nbins=num_batch * nbins,
                                        dtype=dtype)

    return tf.reshape(hist, tf.concat([batch_dim, [nbins]], 0))
Ejemplo n.º 4
0
def contrast(image, factor):
  """Equivalent of PIL Contrast."""
  degenerate = tf.image.rgb_to_grayscale(image)
  # Cast before calling tf.histogram.
  degenerate = tf.cast(degenerate, tf.int32)

  # Compute the grayscale histogram, then compute the mean pixel value,
  # and create a constant image size of that value.  Use that as the
  # blending degenerate target of the original image.
  hist = tf.histogram_fixed_width(degenerate, [0, 255], nbins=256)
  mean = tf.reduce_sum(tf.cast(hist, tf.float32)) / 256.0
  degenerate = tf.ones_like(degenerate, dtype=tf.float32) * mean
  degenerate = tf.clip_by_value(degenerate, 0.0, 255.0)
  degenerate = tf.image.grayscale_to_rgb(tf.cast(degenerate, tf.uint8))
  return blend(degenerate, image, factor)
Ejemplo n.º 5
0
    def get_jh(x, y, value_range, nbins):
        dtype = tf.dtypes.int32
        x_range = value_range[0]
        y_range = value_range[1]
        histy_bins = tf.histogram_fixed_width_bins(y,
                                                   y_range,
                                                   nbins=nbins,
                                                   dtype=dtype)

        def masking_info(tf_val):
            return tf.math.equal(histy_bins, tf_val)

        H = tf.map_fn(
            lambda i: tf.histogram_fixed_width(
                x[masking_info(i)], x_range, nbins=nbins), tf.range(nbins))

        return H
Ejemplo n.º 6
0
def idx2csr(indices, rows, columns):
    """Convert index format meta-data to compressed sparse row format.

  Args:
    indices: Tensor, the linear indices for the sparse matrix.
    rows: Tensor, the number of rows in the sparse matrix.
    columns: Tensor, the number of columns in the sparse matrix.

  Returns:
    row_indices: Tensor, the row indices sorted by size.
    row_offset: Tensor, the offsets for each row in the sparse matrix.
    column_indices: Tensor, the column indices for each nonzero in the
      matrix.
  """
    # Calculate the length of each row by histogramming the indices.
    row_lengths = tf.histogram_fixed_width(indices, [0, rows * columns],
                                           nbins=rows)

    row_offsets = tf.concat([[0], tf.cumsum(row_lengths)], axis=0)
    row_indices = tf.argsort(row_lengths, direction="DESCENDING")
    column_indices = tf.mod(indices, columns)
    return row_indices, row_offsets, column_indices
Ejemplo n.º 7
0
    def add_single_image_info(self, image_id, eval_dict):
        groundtruth_boxes = eval_dict[
            standard_fields.InputDataFields.groundtruth_boxes]
        groundtruth_classes = eval_dict[
            standard_fields.InputDataFields.groundtruth_classes]
        detection_boxes = eval_dict[
            standard_fields.DetectionResultFields.detection_boxes]
        detection_scores = eval_dict[
            standard_fields.DetectionResultFields.detection_scores]
        detection_classes = eval_dict[
            standard_fields.DetectionResultFields.detection_classes]

        groundtruth_has_rotation = groundtruth_classes > 1
        groundtruth_boxes_with_rotation = groundtruth_boxes[
            groundtruth_has_rotation]

        #ensure classes are both not 'dot' class, so they have a meaningful rotation value
        detection_within_score = detection_scores > self._score_threshold
        detection_class_has_rotation = detection_classes > 1
        detection_has_rotation_and_score = tf.logical_and(
            detection_within_score, detection_class_has_rotation)
        detection_boxes_within_score = detection_boxes[
            detection_has_rotation_and_score]
        detection_classes_within_score = detection_classes[
            detection_has_rotation_and_score]

        gt_boxlist = box_list.BoxList(
            tf.convert_to_tensor(groundtruth_boxes_with_rotation))
        det_boxlist = box_list.BoxList(
            tf.convert_to_tensor(detection_boxes_within_score))

        detection_y_rotation_angles = eval_dict[
            additional_fields.DetectionResultFields.y_rotation_angles]
        groundtruth_y_rotation_angles = eval_dict[
            additional_fields.GroundtruthResultFields.y_rotation_angles]
        detection_y_rotation_angles_within_score = detection_y_rotation_angles[
            detection_has_rotation_and_score]

        for iou_threshold, assigner in self._iou_thresholds_and_assigners:
            cls_targets, cls_weights, reg_targets, reg_weights, match = assigner.assign(
                det_boxlist, gt_boxlist)

            fg_detections = match >= 0
            fg_detection_boxes = detection_boxes_within_score[fg_detections, :]
            fg_matches = match[fg_detections]

            fg_matches_argsort = tf.argsort(fg_matches)
            fg_matches_sorted = tf.gather(fg_matches, fg_matches_argsort)

            gt_match_indices, fg_match_sorted_indices_with_repeats, fg_match_sorted_indices_counts = tf.unique_with_counts(
                fg_matches_sorted)
            fg_match_sorted_indices_no_repeats = tf.cumsum(
                tf.pad(fg_match_sorted_indices_counts, [[1, 0]]))[:-1]

            fg_match_indices_no_repeats = tf.gather(
                fg_matches_argsort, fg_match_sorted_indices_no_repeats)

            def get_matches_and_angle_difference(fg_match_idx_tensor,
                                                 gt_match_idx_tensor):
                if debug_get_matching_boxes:
                    gt_matching_detection_boxes = tf.gather(
                        groundtruth_boxes_with_rotation,
                        gt_match_idx_tensor,
                        axis=0)
                    fg_matching_detection_boxes = tf.gather(
                        fg_detection_boxes, fg_match_idx_tensor, axis=0)
                    pass

                fg_matching_detection_y_rot_angles = tf.gather(
                    detection_y_rotation_angles_within_score,
                    fg_match_idx_tensor,
                    axis=0)

                groundtruth_y_rotation_angles_matches = tf.gather(
                    groundtruth_y_rotation_angles, gt_match_idx_tensor, axis=0)
                groundtruth_has_y_rot = tf.math.logical_not(
                    tf.math.equal(groundtruth_y_rotation_angles_matches, 0))
                groundtruth_existant_y_rot_angle = groundtruth_y_rotation_angles_matches[
                    groundtruth_has_y_rot]

                detection_existant_y_rot_angle = fg_matching_detection_y_rot_angles[
                    groundtruth_has_y_rot]

                angle_diff = detection_existant_y_rot_angle - groundtruth_existant_y_rot_angle
                angle_diff_unwrapped = tf.math.atan2(tf.math.sin(angle_diff),
                                                     tf.math.cos(angle_diff))
                angle_diff_abs = tf.math.abs(angle_diff_unwrapped)

                n_angle_matches = len(angle_diff)

                return n_angle_matches, angle_diff_abs

            num_angle_matches, abs_angle_differences = get_matches_and_angle_difference(
                fg_match_indices_no_repeats, gt_match_indices)
            angle_diff_sum_square = tf.reduce_sum(
                tf.math.square(abs_angle_differences * 180 / np.pi))
            match_angle_diff_histogram = tf.histogram_fixed_width(
                abs_angle_differences * 180 / np.pi,
                self._histogram_range,
                nbins=self._num_angle_bins,
                dtype=tf.dtypes.int32)

            self.total_num_angle_matches[iou_threshold] += num_angle_matches
            self.total_angle_diff_sum_squared[
                iou_threshold] += angle_diff_sum_square
            self.angle_histograms[iou_threshold] += match_angle_diff_histogram