Search code examples
pythonopencvimage-processing

Extract Foreground from Background by making the background white


Thanks Your time, I am a newbie in opencv and I want to extract foreground from my image by making the background white. So far, I have been able to convert the image background to black, how can I make it white..??

Input Image and Output Image

import numpy as np
import cv2 as cv
import cv2
import glob
import os


image_data_path = os.path.abspath('../8470p/corn_weed_datasets/bluegrass')
gt_data_path = os.path.abspath('../8470p/GT data')
image_out_path = os.path.abspath('../8470p/corn_weed_datasets/corn1')

curr_image = 0 


for image_name in sorted(os.listdir(image_data_path)):

    curr_image += 1


    image_path = os.path.join(image_data_path, image_name)

    img = cv2.imread(image_path)



    hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)


    l_b = np.array([23,26,12])
    # the array is the our range of lower blue colors
    u_b = np.array([277,255,277])
    # the array is the our range of upper blue colors
    mask = cv.inRange(hsv, l_b, u_b)
    # threshold d hsv image to get only d blue color
    res = cv2.bitwise_and(img,img, mask = mask)

    Image = cv2.cvtColor(res, cv2.COLOR_RGB2BGR)

    cv.imshow('res',Image)
    k = cv.waitKey(0) & 0xFF
    if k ==27:
        break
for bb,file in enumerate (glob.glob(image_data_path)):
    cv2.imwrite('../8470p/corn_weed_datasets/corn1/bluegrass{}.png'.format(bb), Image)
#     cv2.imwrite(os.path.join(image_out_path,Image ))


cv.destroyAllWindows()

Solution

  • Here is one way to do that in Python/OpenCV

    • Read the input
    • Convert to HSV color space
    • Do color thresholding on the green colors
    • Apply morphology to the thresholded image to remove extraneous white regions and save a mask
    • Apply the mask to the input image
    • Change black to white
    • Save the results


    Input:

    enter image description here

    import cv2
    import numpy as np
    
    # load image
    img = cv2.imread("green_plant.jpg")
    
    # convert to hsv
    hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    
    # threshold using inRange
    range1 = (30,0,100)
    range2 = (255,255,255)
    mask = cv2.inRange(hsv,range1,range2)
    
    # apply morphology closing and opening to mask
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    
    # make mask 3 channel
    mask = cv2.merge([mask,mask,mask])
    
    # invert mask
    mask_inv = 255 - mask
    
    # create white image for background
    white = np.full_like(img, (255,255,255))
    
    # apply mask to input
    img_masked = cv2.bitwise_and(img, mask)
    
    # apply inverted mask to white image
    white_masked = cv2.bitwise_and(white, mask_inv)
    
    # combine inverted mask with masked image
    result = cv2.add(img_masked, mask_inv)
    
    # write result to disk
    cv2.imwrite("green_plant_mask.png", mask)
    cv2.imwrite("green_plant_white_background.jpg", result)
    
    # display it
    cv2.imshow("mask", mask)
    cv2.imshow("mask_inv", mask_inv)
    cv2.imshow("img_masked", img_masked)
    cv2.imshow("result", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    


    Mask:

    enter image description here

    Input masked:

    enter image description here

    Result:

    enter image description here