RadAstronomer
RadAstronomer

Reputation: 1

Converting the black color in the binary image to the RGB color green

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

Answers (2)

fmw42
fmw42

Reputation: 53081

Here is perhaps a better way (producing more natural varying green) using Python/OpenCV.

  • Read the input
  • Convert to HSV and separate the saturation channel
  • Make black everyting in the saturation channel below some threshold (for a mask)
  • Convert the saturation mask to 3 channel float in the range of 0 to 1
  • Create a green image the size of the input
  • Use the mask to blend between the input and the green image
  • Save the results

Input:

enter image description here

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:

enter image description here

Result:

enter image description here

Upvotes: 1

fmw42
fmw42

Reputation: 53081

You can do that in Python/OpenCV as follows:

  • Read the input
  • Threshold using cv2.inRange() to create a mask
  • Use Numpy and the mask to change the color from "black" to green
  • Save the results

Input:

enter image description here

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:

enter image description here

Result Image:

enter image description here

Upvotes: 1

Related Questions