MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / connected_components

Function connected_components

tensorflow/contrib/image/python/ops/image_ops.py:469–533  ·  view source on GitHub ↗

Labels the connected components in a batch of images. A component is a set of pixels in a single input image, which are all adjacent and all have the same non-zero value. The components using a squared connectivity of one (all True entries are joined with their neighbors above, below, left,

(images)

Source from the content-addressed store, hash-verified

467
468
469def connected_components(images):
470 """Labels the connected components in a batch of images.
471
472 A component is a set of pixels in a single input image, which are all adjacent
473 and all have the same non-zero value. The components using a squared
474 connectivity of one (all True entries are joined with their neighbors above,
475 below, left, and right). Components across all images have consecutive ids 1
476 through n. Components are labeled according to the first pixel of the
477 component appearing in row-major order (lexicographic order by
478 image_index_in_batch, row, col). Zero entries all have an output id of 0.
479
480 This op is equivalent with `scipy.ndimage.measurements.label` on a 2D array
481 with the default structuring element (which is the connectivity used here).
482
483 Args:
484 images: A 2D (H, W) or 3D (N, H, W) Tensor of boolean image(s).
485
486 Returns:
487 Components with the same shape as `images`. False entries in `images` have
488 value 0, and all True entries map to a component id > 0.
489
490 Raises:
491 TypeError: if `images` is not 2D or 3D.
492 """
493 with ops.name_scope("connected_components"):
494 image_or_images = ops.convert_to_tensor(images, name="images")
495 if len(image_or_images.get_shape()) == 2:
496 images = image_or_images[None, :, :]
497 elif len(image_or_images.get_shape()) == 3:
498 images = image_or_images
499 else:
500 raise TypeError(
501 "images should have rank 2 (HW) or 3 (NHW). Static shape is %s" %
502 image_or_images.get_shape())
503 components = gen_image_ops.image_connected_components(images)
504
505 # TODO(ringwalt): Component id renaming should be done in the op, to avoid
506 # constructing multiple additional large tensors.
507 components_flat = array_ops.reshape(components, [-1])
508 unique_ids, id_index = array_ops.unique(components_flat)
509 id_is_zero = array_ops.where_v2(math_ops.equal(unique_ids, 0))[:, 0]
510 # Map each nonzero id to consecutive values.
511 nonzero_consecutive_ids = math_ops.range(
512 array_ops.shape(unique_ids)[0] - array_ops.shape(id_is_zero)[0]) + 1
513
514 def no_zero():
515 # No need to insert a zero into the ids.
516 return nonzero_consecutive_ids
517
518 def has_zero():
519 # Insert a zero in the consecutive ids where zero appears in unique_ids.
520 # id_is_zero has length 1.
521 zero_id_ind = math_ops.cast(id_is_zero[0], dtypes.int32)
522 ids_before = nonzero_consecutive_ids[:zero_id_ind]
523 ids_after = nonzero_consecutive_ids[zero_id_ind:]
524 return array_ops.concat([ids_before, [0], ids_after], axis=0)
525
526 new_ids = control_flow_ops.cond(

Callers

nothing calls this directly

Calls 8

reshapeMethod · 0.80
equalMethod · 0.80
name_scopeMethod · 0.45
get_shapeMethod · 0.45
rangeMethod · 0.45
shapeMethod · 0.45
condMethod · 0.45
gatherMethod · 0.45

Tested by

no test coverage detected