What would be the best way to remove the background from this photo?
I've tried converted to HSV and using inRange to get a mask, but it doesn't pick up the plant fully, and includes some of the mortar between the brickwork.
What would be the best way to remove the background from this photo?
I've tried converted to HSV and using inRange to get a mask, but it doesn't pick up the plant fully, and includes some of the mortar between the brickwork.
Since there seems to be a clear distinction between the desired plant and the background, I recommend color thresholding with a lower and upper threshold range to isolate the desired regions. The idea is to convert the image to HSV format, color threshold to obtain a mask, then bitwise-and. I think you have the right approach but had trouble determining the lower and upper ranges. Using this lower/upper range:
hsv_lower = np.array([41,57,78])
hsv_upper = np.array([145,255,255])
import cv2
import numpy as np
image = cv2.imread("1.jpg")
original = image.copy()
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
hsv_lower = np.array([41,57,78])
hsv_upper = np.array([145,255,255])
mask = cv2.inRange(hsv, hsv_lower, hsv_upper)
result = cv2.bitwise_and(original, original, mask=mask)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey()
To determine the lower and upper range, we can use a color thresholder HSV script
import cv2
import sys
import numpy as np
def nothing(x):
pass
# Load in image
image = cv2.imread('1.jpg')
# Create a window
cv2.namedWindow('image')
# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
cv2.createTrackbar('SMin','image',0,255,nothing)
cv2.createTrackbar('VMin','image',0,255,nothing)
cv2.createTrackbar('HMax','image',0,179,nothing)
cv2.createTrackbar('SMax','image',0,255,nothing)
cv2.createTrackbar('VMax','image',0,255,nothing)
# Set default value for MAX HSV trackbars.
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)
# Initialize to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0
output = image
wait_time = 33
while(1):
# get current positions of all trackbars
hMin = cv2.getTrackbarPos('HMin','image')
sMin = cv2.getTrackbarPos('SMin','image')
vMin = cv2.getTrackbarPos('VMin','image')
hMax = cv2.getTrackbarPos('HMax','image')
sMax = cv2.getTrackbarPos('SMax','image')
vMax = cv2.getTrackbarPos('VMax','image')
# Set minimum and max HSV values to display
lower = np.array([hMin, sMin, vMin])
upper = np.array([hMax, sMax, vMax])
# Create HSV Image and threshold into a range.
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
output = cv2.bitwise_and(image,image, mask= mask)
# Print if there is a change in HSV value
if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
phMin = hMin
psMin = sMin
pvMin = vMin
phMax = hMax
psMax = sMax
pvMax = vMax
# Display output image
cv2.imshow('image',output)
# Wait longer to prevent freeze for videos.
if cv2.waitKey(wait_time) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()