-3

I am trying to remove the backgrounds of a set of tea leaf images.

I tried these codes in StackOverflow itself but they don't work with my images.

How can I delete the whole background around the leaf and keep only the single leaf.

This is a one-sample of the image set.

enter image description here

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Katara
  • 66
  • 1
  • 10
  • What is "background" in this case? How did the approaches you linked fail to work? – beaker Oct 10 '21 at 14:42
  • I need to remove the whole background around the leaf. The approaches mentioned above didn't remove the whole background around the leaf – Katara Oct 10 '21 at 14:44
  • So, you consider everything except the single leaf to be background? – beaker Oct 10 '21 at 14:45
  • Yes that's right – Katara Oct 10 '21 at 14:46
  • I just upvoted as it's an interesting question. I've had a similar problem where I custom rigged a solution together, where I wanted to detect if the background in an image was light enough for our purposes. The solutions mentioned in the linked articles didn't work for me either. – rv.kvetch Oct 10 '21 at 14:49
  • 1
    Then it seems to me that the approach in your first link should work quite well. You might need to first mask the entire area of the white card (including the leaf) so that the stem doesn't connect to the leafy background. – beaker Oct 10 '21 at 14:52
  • @Katara do all your images have a similar pattern where there is a white page behind the leaf? If so there is a simple method that does come to mind – veedata Oct 10 '21 at 15:04
  • You would find it much easier if you can photograph the leaf on a completely white background, that is using the full background card so that no other leaves or other texture shows in your image. – fmw42 Oct 10 '21 at 16:24

1 Answers1

0
# Read image 
img = cv2.imread('leaf.jpg')

# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Find edges
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]

# Find contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
# Sort contour by area
contours = sorted(contours, key=cv2.contourArea, reverse=True)

# Find the bounding box and crop image to get ROI 
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    ROI = img[y:y+h, x:x+w]
    break

# Define lower and upper threshold for background
lower = np.array([128, 128, 128])
upper = np.array([255, 255, 255])

# Create mask to only select black
thresh = cv2.inRange(ROI, lower, upper)

# Apply morphology
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# invert morph image to get background as black
mask = 255 - morph

# apply mask to image
result = cv2.bitwise_and(ROI, ROI, mask=mask)

plt.imshow(result)

enter image description here

afs
  • 45
  • 6