Neel
Neel

Reputation: 59

Remove Background from Image having a fixed background

I am trying to remove a fixed background from an image with a single free-falling object. The image has a single free falling object and it has a white background with a circular patch in the middle.

Test cases worked

Below is my code for the above task. I have used OpenCV BackgroundSubtractorKNN and BackgroundSubtractorMOG2 algorithm to achieve this task. The left images should be given as input and the code should produce the right images as output.

import numpy as np
import cv2
import sys
import os

#backgroundSubtractor = cv2.createBackgroundSubtractorMOG2()

backgroundSubtractor = cv2.createBackgroundSubtractorKNN()

# apply the algorithm for background images using learning rate > 0
for i in range(1, 16):
    bgImageFile = "background/BG.png" 
    print("Opening background", bgImageFile)
    bg = cv2.imread(bgImageFile)
    backgroundSubtractor.apply(bg, learningRate=0.5)

# apply the algorithm for detection image using learning rate 0

dirc = os.getcwd()
filepath = os.path.join(dirc,'data')
if not os.path.exists('saved_bgRemoved'):
    os.makedirs('saved_bgRemoved')

for file in os.listdir(filepath):
    stillFrame = cv2.imread(os.path.join(filepath,file))
    fgmask = backgroundSubtractor.apply(stillFrame, learningRate=0)
   
    bgImg = cv2.bitwise_and(stillFrame,stillFrame,mask=fgmask)
    # show both images
    cv2.imshow("original", stillFrame)
    cv2.imshow("mask", fgmask)
    cv2.imshow("Cut Image", bgImg)
    cv2.waitKey()
    cv2.destroyAllWindows()
    cv2.imwrite(os.path.join('saved_bgRemoved',file), bgImg)

My code works very well with the above dataset, but it fails to work with the image data below:

Test Case that doesn't work

It also doesn't work if the object is colored in greyish texture. I think it works well when the pixel distribution of the object is uniform and different from the background (i.e. the circular patch).

Is there any other best way to achieve this task, so that it can subtract the background even from the hollow area of the object, without subtracting parts of the object?

Upvotes: 0

Views: 1428

Answers (1)

Shoaib Mirzaei
Shoaib Mirzaei

Reputation: 522

use below code, I think it now works

import cv2, os

def remove_bg(bg_path,im_path):
    bg = cv2.imread(bg_path)
    im = cv2.imread(im_path)
    row,col,_ = im.shape
    for i in range(0,row):
        for j in range(0,col):
            if ( bg[i][j][0] == im[i][j][0] and bg[i][j][1] == im[i][j][1] and bg[i][j][2] == im[i][j][2] ):
                im[i][j] = [0,0,0] #it will replace background with black color, you can change it for example to [255,0,0] to replace it with red
    return(im)

directory,_=os.path.split(__file__)
bg_path = directory + "\\background.png"
im_path = directory + "\\data6.png"
result = remove_bg(bg_path,im_path)
cv2.imshow("result", result)
cv2.waitKey()
cv2.imwrite(directory + "\\Result.png", result)

Upvotes: 1

Related Questions