-2

I need to automatically recognise any scratches of a coin, that are on the "clear" part (not the shape).

I have used edge detection to create an outline of the shape, and now I am thinking of using masking to completely remove it, allowing me then to use another code to count any other lines that were on the clear part and would be scratches. My image is already on a grayscale. Does anyone have any ideas on what code I could use to achieve this? Thank you!

Coin I need to extract any scratches from (This one does not have any):

Outline of the frosted part using edge detection

Dan Mašek
  • 17,852
  • 6
  • 57
  • 85
  • 2
    I do not understand your problem -- what is frosted? Could you show an example of the mask or mark where you need the mask to be white. Why are you getting edges rather than thresholding? – fmw42 Feb 09 '23 at 17:44
  • @fmw42 Frosting - An effect in which parts of a coin are slightly dulled (using sandblasting techniques) to provide a contrast to the shinier parts of metal. | (Not that I can really see anything matching that definition on the provided sample image) – Dan Mašek Feb 09 '23 at 20:07
  • Apologies for the confusing dectription. The "frosted" part is the shaped part. So what I need to do is to remove the shape that is depicted on the coin. – Ioanna Deroukaki Feb 10 '23 at 19:56
  • The "clear" part means nothing to me. –  Feb 12 '23 at 14:21

1 Answers1

1

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:

enter image description here

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:

enter image description here

Morphology cleaned image:

enter image description here

Mask result image:

enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80