Reputation: 55
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
image 2
Desired result
Upvotes: 2
Views: 699
Reputation: 27577
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:
Upvotes: 1
Reputation: 370
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)
Upvotes: 1
Reputation: 53184
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)
Upvotes: 1