3

I am trying to highlight differences between two almost similar image masks using OpenCV's BackgroundSubtractorMOG2 method.

My Code:

def Approach_2():
    img = [0, 0]
    img[0] = cv2.imread('images/4-left.PNG', cv2.IMREAD_GRAYSCALE)
    img[1] = cv2.imread('images/4-right.PNG', cv2.IMREAD_GRAYSCALE)

    img[0], img[1] = make_similar(img[0], img[1]) # make two images similar (equal width and height) by applying scaling, translation and performs Canny edge detection on two images

    fps = 5

    fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=True)

    cv2.imshow("A", img[0])
    cv2.imshow("B", img[1])

    i = 1
    while(True):

        frame = img[i]
        i = 1-i
        fgmask = fgbg.apply(frame)        

        cv2.imshow('original', frame)
        cv2.imshow('fg', fgmask)
        # cv2.imshow('fg', cv2.bitwise_and(frame, frame, mask=fgmask))

        time.sleep(1 / fps)

        if(cv2.waitKey(1) & 0xFF == ord('q')) : break

    cv2.destroyAllWindows()

if __name__ == '__main__':
    Approach_2()

But i am getting only blank 'fgmask'. enter image description here

Any suggestions. ?

  • Isn't that a bit of an overkill to use MOG background subtractor (with shadow detection) to find the difference of two binary images? IMHO a `bitwise_and` to get points that are same, `bitwise_xor` to get points that differ between the two, etc. – Dan Mašek Dec 09 '18 at 16:56
  • Actually the two images are not that much similar (pixel wise) to apply bitwise operations on them. – Abhishek Aggarwal Dec 09 '18 at 17:42

2 Answers2

2

As stated in the comments, you should bitwise operations. It is easier and far more efficient. You can read about it here

To add some extra information: a backgroundsubtractor can (with some trickery) be used on still images, but it is intended for video. You can find sample code here

As to your code, it does not establish a solid background, because it alternates the two source images on every frame. Therefor the result is a blank mask.

J.D.
  • 4,511
  • 2
  • 7
  • 20
1

Give this a try and see how that works:

while(True):

    f1 = img[0]
    f2 = img[1]
    fg1 = fgbg.apply(f1)
    fb2 = fgbg.apply(f2)

    cv2.imshow('original', frame)
    cv2.imshow('fg1', fg1)
    cv2.imshow('fg2', fb2)
    # cv2.imshow('fg', cv2.bitwise_and(frame, frame, mask=fgmask))

    time.sleep(1 / fps)

    if(cv2.waitKey(1) & 0xFF == ord('q')) : break

cv2.destroyAllWindows()
MNM
  • 2,673
  • 6
  • 38
  • 73