How do I remove the black background in the Image?

Viewed 510
  • The images below contain a bean and a stone respectively on a black flipper.

  • I want to isolate only the object on the flipper in the below. I have use cv2.inRange() but the result is still bad.

  • I have written a sample code below:

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

img_blured = cv2.blur(gray, (5, 5))
ret, thres = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)

neg = cv2.bitwise_not(thres)
erosion = cv2.erode(neg, np.ones((6, 6), np.uint8), iterations=1)
cv2.imshow("erosion", erosion)

# ret, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY)
img[erosion == 0] = 0

image 1

enter image description here

image 2

enter image description here

Desired result

enter image description here

3 Answers
hsv_image = cv2.cvtColor(img ,cv2.COLOR_BGR2HSV)
lower_orange_yellow = np.array([10, 50, 150])
upper_orange_yellow = np.array([35, 255, 255])
y_mask = cv2.inRange(hsv_image , lower_orange_yellow , upper_orange_yellow)
img[y_mask==0]=(0,0,0)

enter image description here

Here is one way to do that in Python/OpenCV.

Your bean color is yellow/orange.

I note that in LAB colorspace, "the A axis is relative to the green–red opponent colors, with negative values toward green and positive values toward red. The B axis represents the blue–yellow opponents, with negative numbers toward blue and positive toward yellow." See https://en.wikipedia.org/wiki/CIELAB_color_space

So the idea is to threshold the B channel of LAB.

import cv2
import numpy as np

# read image
img1 = cv2.imread('bean1.jpg')
img2 = cv2.imread('bean2.jpg')

# convert to LAB and extract the B channel
B1 = cv2.cvtColor(img1, cv2.COLOR_BGR2LAB)[:,:,2]
B2 = cv2.cvtColor(img2, cv2.COLOR_BGR2LAB)[:,:,2]

# threshold on B channel
thresh1 = cv2.threshold(B1, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
thresh2 = cv2.threshold(B2, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply threshold as mask to image to blacken unwanted areas
result1 = img1.copy()
result1[thresh1==0] = (0,0,0)
result2 = img2.copy()
result2[thresh2==0] = (0,0,0)

# write results to disk
cv2.imwrite("bean1_extracted.png", result1)
cv2.imwrite("bean2_extracted.png", result2)

# display it
cv2.imshow("B1", B1)
cv2.imshow("B2", B2)
cv2.imshow("THRESH1", thresh1)
cv2.imshow("THRESH2", thresh2)
cv2.imshow("RESULT1", result1)
cv2.imshow("RESULT2", result2)
cv2.waitKey(0)

You'll need to define an HSV mask:

import cv2
import numpy as np

lower = np.array([6, 64, 0])
upper = np.array([23, 255, 255])

imgs = ["bean.jpg", "stone.jpg"]

for name in imgs:
    img = cv2.imread(name)
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(img_hsv, lower, upper)
    img_masked = cv2.bitwise_and(img, img, mask=mask)
    cv2.imshow(name, img_masked)

cv2.waitKey(0)

Output:

enter image description here

enter image description here

Related