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)