@ -29,7 +29,7 @@ def find_object_to_grasp(height_image, display_on=False):
if display_on :
if display_on :
print ( ' No elevated surface found. ' )
print ( ' No elevated surface found. ' )
return None
return None
surface_height_pix = np . max ( h_image [ surface_mask > 0 ] )
surface_height_pix = np . max ( h_image [ surface_mask > 0 ] )
surface_height_m = m_per_unit * surface_height_pix
surface_height_m = m_per_unit * surface_height_pix
height_image . apply_planar_correction ( plane_parameters , surface_height_pix )
height_image . apply_planar_correction ( plane_parameters , surface_height_pix )
@ -42,11 +42,24 @@ def find_object_to_grasp(height_image, display_on=False):
rgb_image = height_image . rgb_image . copy ( )
rgb_image = height_image . rgb_image . copy ( )
rgb_image [ surface_mask > 0 ] = ( rgb_image [ surface_mask > 0 ] / 2 ) + [ 0 , 127 , 0 ]
rgb_image [ surface_mask > 0 ] = ( rgb_image [ surface_mask > 0 ] / 2 ) + [ 0 , 127 , 0 ]
#####################################
# Select candidate object points
# Define the minimum height for a candidate object point
min_object_height_m = 0.01
min_object_height_m = 0.01
min_obstacle_height_m = surface_height_m + min_object_height_m
min_obstacle_height_m = surface_height_m + min_object_height_m
min_obstacle_height_pix = min_obstacle_height_m / m_per_unit
min_obstacle_height_pix = min_obstacle_height_m / m_per_unit
obstacle_selector = h_image > min_obstacle_height_pix
# Define the maximum height for a candidate object point
robot_camera_height_m = 1.13 #from HeadScan in mapping.py and ManipulationView in manipulation_planning.py)
voi_safety_margin_m = 0.02
max_object_height_m = 0.4
max_obstacle_height_m = min ( robot_camera_height_m - voi_safety_margin_m ,
surface_height_m + max_object_height_m )
max_obstacle_height_pix = max_obstacle_height_m / m_per_unit
# Select candidate object points that are within the valid height range
obstacle_selector = ( h_image > min_obstacle_height_pix ) & ( h_image < max_obstacle_height_pix )
if display_on :
if display_on :
rgb_image = height_image . rgb_image . copy ( )
rgb_image = height_image . rgb_image . copy ( )
@ -61,11 +74,18 @@ def find_object_to_grasp(height_image, display_on=False):
rgb_image [ surface_mask > 0 ] = ( rgb_image [ surface_mask > 0 ] / 2 ) + [ 0 , 127 , 0 ]
rgb_image [ surface_mask > 0 ] = ( rgb_image [ surface_mask > 0 ] / 2 ) + [ 0 , 127 , 0 ]
rgb_image [ obstacle_mask > 0 ] = ( rgb_image [ obstacle_mask > 0 ] / 2 ) + [ 0 , 0 , 127 ]
rgb_image [ obstacle_mask > 0 ] = ( rgb_image [ obstacle_mask > 0 ] / 2 ) + [ 0 , 0 , 127 ]
# Find the convex hull of the surface points to represent the full
# surface, overcoming occlusion holes, noise, and other phenomena.
surface_convex_hull_mask = convex_hull_image ( surface_mask )
surface_convex_hull_mask = convex_hull_image ( surface_mask )
# Select candidate object points that are both within the valid
# height range and on the surface
obstacles_on_surface_selector = ( obstacle_selector & surface_convex_hull_mask )
obstacles_on_surface_selector = ( obstacle_selector & surface_convex_hull_mask )
obstacles_on_surface = np . uint8 ( 255.0 * obstacles_on_surface_selector )
obstacles_on_surface = np . uint8 ( 255.0 * obstacles_on_surface_selector )
# Dilate and erode the obstacles to agglomerate object parts.
# Dilate and erode the candidate object points to agglomerate
# object parts that might be separated due to occlusion, noise,
# and other phenomena.
kernel_width_pix = 5 #3
kernel_width_pix = 5 #3
iterations = 3 #5
iterations = 3 #5
kernel_radius_pix = ( kernel_width_pix - 1 ) / 2
kernel_radius_pix = ( kernel_width_pix - 1 ) / 2
@ -78,6 +98,10 @@ def find_object_to_grasp(height_image, display_on=False):
if use_erosion :
if use_erosion :
obstacles_on_surface = cv2 . erode ( obstacles_on_surface , kernel , iterations = iterations )
obstacles_on_surface = cv2 . erode ( obstacles_on_surface , kernel , iterations = iterations )
#####################################
# Process the candidate object points
# Treat connected components of candidate object points as objects. Fit ellipses to these segmented objects.
label_image , max_label_index = sk . measure . label ( obstacles_on_surface , neighbors = 8 , background = 0 , return_num = True , connectivity = None )
label_image , max_label_index = sk . measure . label ( obstacles_on_surface , neighbors = 8 , background = 0 , return_num = True , connectivity = None )
region_properties = sk . measure . regionprops ( label_image , intensity_image = None , cache = True , coordinates = ' xy ' )
region_properties = sk . measure . regionprops ( label_image , intensity_image = None , cache = True , coordinates = ' xy ' )
if display_on :
if display_on :
@ -85,7 +109,10 @@ def find_object_to_grasp(height_image, display_on=False):
color_label_image = sk . color . label2rgb ( label_image , image = rgb_image , colors = None , alpha = 0.3 , bg_label = 0 , bg_color = ( 0 , 0 , 0 ) , image_alpha = 1 , kind = ' overlay ' )
color_label_image = sk . color . label2rgb ( label_image , image = rgb_image , colors = None , alpha = 0.3 , bg_label = 0 , bg_color = ( 0 , 0 , 0 ) , image_alpha = 1 , kind = ' overlay ' )
cv2 . imshow ( ' color_label_image ' , color_label_image )
cv2 . imshow ( ' color_label_image ' , color_label_image )
if len ( region_properties ) > 0 :
# Proceed if an object was found.
if len ( region_properties ) > 0 :
# Select the object with the largest area.
largest_region = None
largest_region = None
largest_area = 0.0
largest_area = 0.0
for region in region_properties :
for region in region_properties :
@ -93,16 +120,21 @@ def find_object_to_grasp(height_image, display_on=False):
largest_region = region
largest_region = region
largest_area = region . area
largest_area = region . area
# Make the object with the largest area the grasp target. In
# the future, other criteria could be used, such as the
# likelihood that the gripper can actually grasp the
# object. For example, the target object might be too large.
object_region = largest_region
object_region = largest_region
# Collect and compute various features for the target object.
object_ellipse = get_ellipse ( object_region )
object_ellipse = get_ellipse ( object_region )
object_area_m_sqr = object_region . area * pow ( m_per_pix , 2 )
object_area_m_sqr = object_region . area * pow ( m_per_pix , 2 )
min_row , min_col , max_row , max_col = object_region . bbox
min_row , min_col , max_row , max_col = object_region . bbox
object_bounding_box = { ' min_row ' : min_row , ' min_col ' : min_col , ' max_row ' : max_row , ' max_col ' : max_col }
object_bounding_box = { ' min_row ' : min_row , ' min_col ' : min_col , ' max_row ' : max_row , ' max_col ' : max_col }
# Only compute height statistics using the
# original, high-confidence heights above the
# surface that are a part of the final object
# region.
# Only compute height statistics using the original,
# high-confidence heights above the surface that are a part of
# the final object region.
object_selector = ( label_image == object_region . label )
object_selector = ( label_image == object_region . label )
object_height_selector = obstacles_on_surface_selector & object_selector
object_height_selector = obstacles_on_surface_selector & object_selector
object_heights_m = ( m_per_unit * h_image [ object_height_selector ] ) - surface_height_m
object_heights_m = ( m_per_unit * h_image [ object_height_selector ] ) - surface_height_m
@ -123,7 +155,7 @@ def find_object_to_grasp(height_image, display_on=False):
# 'minor': {'axis': minor_axis, 'length': r.minor_axis_length},
# 'minor': {'axis': minor_axis, 'length': r.minor_axis_length},
# 'major': {'axis': major_axis, 'length': r.major_axis_length, 'ang_rad': major_ang_rad}}
# 'major': {'axis': major_axis, 'length': r.major_axis_length, 'ang_rad': major_ang_rad}}
# Create object grasp target .
# Prepare grasp target information .
grasp_location_xy_pix = object_ellipse [ ' centroid ' ]
grasp_location_xy_pix = object_ellipse [ ' centroid ' ]
major_length_pix = object_ellipse [ ' major ' ] [ ' length ' ]
major_length_pix = object_ellipse [ ' major ' ] [ ' length ' ]
major_length_m = m_per_pix * major_length_pix
major_length_m = m_per_pix * major_length_pix