def find_black_center(cv_img, msk):
"""
Given an opencv image containing a dark object on a light background
and a mask of objects to ignore (a gripper, for instance),
return the coordinates of the centroid of the largest object
(excluding those touching edges) and its simplified contour.
If none detected or problem with centroid, return [(-1, -1), False].
"""
# Convert to black and white
(rows, cols, _) = cv_img.shape
grey_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
grey_img = cv2.bilateralFilter(grey_img, 11, 17, 17)
_, outlines = cv2.threshold(
grey_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Subtract gripper
msk_out = cv2.subtract(cv2.bitwise_not(outlines), msk)
# Remove objects touching edges
flood_fill_edges(msk_out, 30)
# Find contours
_, contours, _ = cv2.findContours(
msk_out, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 0:
return [(-1, -1), False]
# Find largest contour
max_area = 0
for cnt in contours:
area = cv2.contourArea(cnt)
if area > max_area:
contour = cnt
max_area = area
# Approximate contour
epsilon = 0.025 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# Find centroid
try:
M = cv2.moments(approx)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
return [(cx, cy), approx]
except ZeroDivisionError:
return [(-1, -1), False]
评论列表
文章目录