I have the following code that works great but it doesn't fill all background. I played with numbers but it either makes all image red or not changing the background.
How can I change the background color of the image?
Picture i want to change its background]:

import cv2
import numpy as np
from google.colab import drive
drive.mount('/content/drive')
image=cv2.imread('/content/drive/MyDrive/tulips.jpg')
r = 720.0 / image.shape[1]
dim = (720, int(image.shape[0] * r))
resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
lower_white = np.array([80, 1, 1],np.uint8) #lower hsv value
upper_white = np.array([130, 255, 255],np.uint8) #upper hsv value
hsv_img = cv2.cvtColor(resized,cv2.COLOR_BGR2HSV)#rgb to hsv color space
#filter the background pixels
frame_threshed = cv2.inRange(hsv_img, lower_white, upper_white)
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(frame_threshed,kernel,iterations = 2)
resized[dilation==255] = (0,0,255) #convert background color
cv2_imshow(resized)
after this code i get this image:

I thought we can simply use cv2.floodFill, and fill the white background with red color.
The issue is that the image is not clean enough - there are JPEG artifacts, and rough edges.
Using cv2.inRange may bring us closer, but assuming there are some white tulips (that we don't want to turn into red), we may have to use floodFill for filling only the background.
I came up with the following stages:
floodFill, on the threshold image - fill the background with the value 128.Code sample:
import cv2
import numpy as np
image = cv2.imread('tulips.jpg')
# Fill the black background with white color
#cv2.floodFill(image, None, seedPoint=(0, 0), newVal=(0, 0, 255), loDiff=(2, 2, 2), upDiff=(2, 2, 2)) # Not working!
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # rgb to hsv color space
s_ch = hsv_img[:, :, 1] # Get the saturation channel
thesh = cv2.threshold(s_ch, 5, 255, cv2.THRESH_BINARY)[1] # Apply threshold - pixels above 5 are going to be 255, other are zeros.
thesh = cv2.morphologyEx(thesh, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))) # Apply opening morphological operation for removing artifacts.
cv2.floodFill(thesh, None, seedPoint=(0, 0), newVal=128, loDiff=1, upDiff=1) # Fill the background in thesh with the value 128 (pixel in the foreground stays 0.
image[thesh == 128] = (0, 0, 255) # Set all the pixels where thesh=128 to red.
cv2.imwrite('tulips_red_bg.jpg', image) # Save the output image.
s_ch (saturation color channel):

thesh after morphological opening, and floodFill:

Output image:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With