Uma Shankar Tewari
Uma Shankar Tewari

Reputation: 56

Image pixel differentiation in opencv Python based on rgb extract and settling

I am using Pyton version 3.* and opencv 3.*. In the below code I want to subtract the whole background on the basis of a corner pixel in order to get the foreground objects

def background_subtract(img,l):
    print("Extract the background pixel")
    image = cv2.imread(img,cv2.IMREAD_ANYCOLOR)
    r,g,b=image[0,0]
    t,d,m= image.shape
    for i in range(t):
        for j in range(d):
            r1,g1,b1=image[i,j]
            if r1>=r:
                r1=0
            if g1>=g:
                g1=0
            if b1>=b:
                b1=0
     path='C:\\Users\\UST\\Desktop'
     if not os.path.exists(path):
     os.makedirs(path)
     cv2.imwrite(os.path.join(path,'background_subtract%d.jpg' %l),image)
     path =os.path.join(path,'%d.jpg' %l)
     print(path)
     return path

But, instead of obtaining the subtracted background image, I am getting my original image instead. Please help

Upvotes: 1

Views: 666

Answers (1)

Patrick Artner
Patrick Artner

Reputation: 51653

You are manipulating the rgb values but not setting them:

for i in range(t):
        for j in range(d):
            r1,g1,b1=image[i,j]
            if r1>=r:
                r1=0
            if g1>=g:
                g1=0
            if b1>=b:
                b1=0
            image[i,j] = [r1,g1,b1]  # this line is missing

Maybe also have a read here: Performance comparison of OpenCV-Python interfaces, cv and cv2

If you are familiar with numpy, cv2 can be manipulated through that a bit faster.

Edit:

You will have a problem with your approach though, if your border pixel is bright red (255,0,0) afterwards your picture will have a red-channel of 0, same for green and blue as you are nulling each pixels red channel if it is "less" than the one on the border.

You could play around with

r,g,b=image[0,0]    # border pixel
delta = 10          # similarity to border pixel 
r_range = range( r-delta, r+delta+1)  
g_range = range( g-delta, g+delta+1)
b_range = range( b-delta, b+delta+1)

and check if all 3 rgb of the pixel you currently see is in its respective range - if so, set it to [0,0,0]:

for i in range(t):
        for j in range(d):
            r1,g1,b1=image[i,j]
            if r1 in r_range and g1 in g_range and b1 in b_range:
                image[i,j] = [0,0,0]  

Upvotes: 2

Related Questions