def _segment_barcode()

in pathology/transformation_pipeline/ingestion_lib/dicom_gen/wsi_to_dicom/barcode_reader.py [0:0]


def _segment_barcode(image_path: str, segmented_image_path: str):
  """Segment the area of barcode from a label image.

  Args:
    image_path: image file path.
    segmented_image_path: segmented image file path if succeed.

  Raises:
    CloudVisionHttpError: if cannot connect to Cloud Vision
    ValueError: if segmentation fails.
  """
  vision_service = cloud_discovery.build('vision', 'v1', cache_discovery=False)

  with open(image_path, 'rb') as image_file:
    content = image_file.read()
  request = vision_service.images().annotate(
      body={
          'requests': [{
              'image': {'content': base64.b64encode(content).decode('UTF-8')},
              'features': [{
                  'type': 'OBJECT_LOCALIZATION',
                  'maxResults': 2,
              }],
          }]
      }
  )
  try:
    response = request.execute()
  except google_api_errors.HttpError as exp:
    raise CloudVisionHttpError(
        'Exception occurred calling cloud vision\n'
        f'exception: {traceback.format_exc()}'
    ) from exp

  try:
    annotations = response['responses'][0]['localizedObjectAnnotations']
  except KeyError as exp:
    raise ValueError(
        'Unexpected cloud vision API response\n'
        f'exception: {traceback.format_exc()}'
    ) from exp

  if not annotations:
    raise ValueError(f'No objects detected in image {image_path}')

  barcode_annotation = None
  for annotation in annotations:
    # The 2D barcode is sometimes recognized as 1D barcode.
    # Overrides the annotation if 2D barcode annotation is found.
    if annotation['name'] == '1D barcode':
      barcode_annotation = annotation
    if annotation['name'] == '2D barcode':
      barcode_annotation = annotation
      break
  if barcode_annotation is None:
    raise ValueError(f'No barcodes detected in image {image_path}')

  original_image = cv2.imread(image_path)
  original_height, original_width, _ = original_image.shape
  try:
    bounding_poly = [
        [v['x'] * original_width, v['y'] * original_height]
        for v in barcode_annotation['boundingPoly']['normalizedVertices']
    ]
  except KeyError as exp:
    cloud_logging_client.warning(
        'Segmentation results missing expected key.', exp
    )
    raise ValueError(f'No barcodes detected in image {image_path}') from exp
  x, y, width, height = cv2.boundingRect(np.array(bounding_poly).astype(int))

  # Padding to avoid edge cut off.
  # 0.1 is just a magic number works well in our dataset.
  padding = 0.1
  y -= int(padding * height)
  x -= int(padding * width)
  height += int(2 * padding * height)
  width += int(2 * padding * width)
  # Clip padded coordinates to imaging.
  y = max(y, 0)
  x = max(x, 0)
  y_max = min(y + height, original_image.shape[0])
  x_max = min(x + width, original_image.shape[1])
  cropped = original_image[y:y_max, x:x_max]
  if cropped.size == 0:
    cloud_logging_client.warning(
        'Segmentation dimensions are zero.',
        dict(x=x, width=width, y=y, height=height),
    )
    raise ValueError(f'No barcodes detected in image {image_path}')
  cv2.imwrite(segmented_image_path, cropped)