Here is one way to get the mask corresponding to the shape of the coin in Python/OpenCV
- Read the image
- Threshold on color
- Apply morphology to clean up some
- Get the coordinates of the white pixels
- Get the convex hull from the coordinates
- Draw a white filled polygon on a black background from the convex hull as the mask result
- Save the results
Input:

import cv2
import numpy as np
# read the input
img = cv2.imread('coin.jpg')
h, w = img.shape[:2]
# threshold on color range
lower = (170,180,230)
upper = (230,230,255)
thresh = cv2.inRange(img, lower, upper)
# apply morphology to clean it up
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
# find all non-zero pixel coordinates
# swap x and y for conversion from numpy y,x to opencv x,y ordering via transpose
coords = np.column_stack(np.where(morph.transpose() > 0))
# get convex hull from coords of non-zero pixels of morph
hull = cv2.convexHull(coords)
# draw convex hull as white filled polygon on black background
mask = np.zeros_like(img)
cv2.fillPoly(mask, [hull], (255,255,255))
# save results
cv2.imwrite('coin_thresh.jpg', thresh)
cv2.imwrite('coin_morph.jpg', morph)
cv2.imwrite('coin_mask.jpg', mask)
# show the results
#cv2.imshow('img2', img2)
cv2.imshow('thresh', thresh)
cv2.imshow('morph', morph)
cv2.imshow('mask', mask)
cv2.waitKey(0)
Threshold image:

Morphology cleaned image:

Mask result image:
