Reputation: 1
So I have created a binary image of a forest picture. My goal is to fill the black areas of the binary image with the RGB color green whilst maintaining the white areas of the binary image. I am still a beginner of python so I apologise in advance for my loose terminology. Below is the code I have to generate the forest picture, converting into greyscale and ultimately to a binary image
First, upload forest picture
import cv2
forest = plt.imread("island.png")
forest[:,:,1] = BURNABLE
print(forest.shape)
print("The image of the forest consists of %i pixels" % (forest.shape[0] * forest.shape[1]))
plt.imshow(forest);
Second, convert forest image into grayscale:
grayed_forest = cv2.cvtColor(forest, cv2.COLOR_BGR2GRAY)
plt.imshow(grayed_forest, cmap = 'gray')
print(grayed_forest.shape)
Third, convert grayed image into binary whilst including ideal threshold value
from skimage.filters import threshold_otsu
thresh = threshold_otsu(grayed_forest)
print(thresh)
binary = grayed_forest > thresh
plt.imshow(binary)
The forest picture for this analysis
DISCLAIMER: I coded this python script in google colab!!!
Essentially, as said in the code, I converted an image, I uploaded, into a binary image using the proper procedures (Converting image to grayscale and then converting that to binary) and now I wish to refill or replace the black areas of the binary image with the color green whilst maintaining the white shades of the binary image
I have found an article similar to my problem without helping my case effectively. The link to it is here: How to change the colors of a binary image using python?
I beg if anyone could help me; i want to genuinely know how it can be done since I feel like I am stuck in this approach.
I appreciate any path to solve this issue of mine. I am eager to learn and open my mind to new ways to solve problems like mine in this case.
Upvotes: 0
Views: 274
Reputation: 53081
Here is perhaps a better way (producing more natural varying green) using Python/OpenCV.
Input:
import cv2
import numpy as np
# read the input
img = cv2.imread('forest.png')
# convert to hsv and get the saturation channel
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
sat = hsv[:,:,1]
# sat seems to be bright at dark spots. so blacken everything else
sat[sat<135] = 0
# convert sat to 3 channel float in range 0 = 1 as mask
mask = sat.astype(np.float32)/255
mask = cv2.merge([mask,mask,mask])
# create green image
green = np.full_like(img, (45,70,50))
# merge the input and green image using sat as mask
result = (img*(1-mask) + green*mask)
result = result.clip(0,255).astype(np.uint8)
# save results
cv2.imwrite('forest_mask2.png', (255*mask).clip(0,255).astype(np.uint8))
cv2.imwrite('forest_result2.png', result)
# show results
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey(0)
Mask Image:
Result:
Upvotes: 1
Reputation: 53081
You can do that in Python/OpenCV as follows:
Input:
import cv2
import numpy as np
# read the image
img = cv2.imread('forest.png')
# threshold on "black" to create mask
lower = (0,0,0)
upper = (20,60,70)
mask = cv2.inRange(img, lower, upper)
# make areas green
result = img.copy()
result[mask==255] = (45,70,50)
# save results
cv2.imwrite('forest_mask.png', mask)
cv2.imwrite('forest_result.png', result)
# show results
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey(0)
Mask Image:
Result Image:
Upvotes: 1