Reputation: 65
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:
Upvotes: 4
Views: 9871
Reputation: 32144
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
:
Upvotes: 3