0

I am using the GMM-algorithm (BackgroundSubtractorMOG2) to find moving objects in a video. The output of this GMM-algorithm is a binary image with white pixels as the pixels that moved, and black pixels as background. I am looking for a way to ignore novel objects entering the field-of-view as long as they are not fully in the field-of-view. Here is an example picture I created: enter image description here

Here, all the white pixels represent moving pixels. The circles are fully in the field-of-view, while the 2 triangles are just about to enter the field-of-view.The left bottom triangle has nearly completely entered the field-of-view, but is still not 100% in the field-of-view. Therefore I still want the left bottom triangle to be completely erased from the frame. Does anyone know a method to deal with this problem?

Thank you

Geox
  • 89
  • 7
  • If you can afford (real-time usage intended?): `cv2.findContours` on the image. For each contour, check if min/max `x`/`y` values are `0` or `image.shape[0]`/`image.shape[1]`, i.e. the contour touches one of the image borders. – HansHirse Apr 12 '21 at 11:13

1 Answers1

0

Try this one:

import numpy as np
import cv2


def edge_filter(image):
    stats = cv2.connectedComponentsWithStats(image, connectivity=8)[2][1:]
    s_x, s_y, s_w, s_h = stats[:, 0], stats[:, 1], stats[:, 2], stats[:, 3]
    res_y, res_x = image.shape
    to_erase = stats[((res_x - s_w - s_x) * (res_y - s_h - s_y) * s_x * s_y) == 0]
    for stat in to_erase:
        x, y, w, h = stat[:4]
        image[y:y+h, x:x+w] = np.zeros((h, w)).astype(np.uint8)


img_in = cv2.imread('bubbles.png',0)
img_out = np.copy(img_in)

edge_filter(img_out)

cv2.imshow('input_image', img_in)
cv2.imshow('output_image', img_out)
cv2.waitKey(0)
cv2.destroyAllWindows()

It works if the other polygons are not overlap the rectangle around the triangles.

But, if you only need to keep the coordinate of the objects, what are not touching the edge, then the code is more simple.

import numpy as np
import cv2


def edge_filter(stats):
    s_x, s_y, s_w, s_h = stats[:, 0], stats[:, 1], stats[:, 2], stats[:, 3]
    res_y, res_x = img.shape
    return stats[((res_x - s_w - s_x) * (res_y - s_h - s_y) * s_x * s_y) != 0]

img = cv2.imread('bubbles.png',0)
stats = cv2.connectedComponentsWithStats(img, connectivity=8)[2][1:]
filtered_stats = edge_filter(stats)

print('stats:\n', stats)
print('filtered stats:\n', filtered_stats)

output:

stats:
[[  627    61   169    61  8145]
 [  171   159    85    91  6053]
 [  309   385    41    25   807]
 [  585   385   221   129 22380]
 [    0   457    80   139  6488]
 [  482   599   225   121 13785]]
filtered stats:
[[  627    61   169    61  8145]
 [  171   159    85    91  6053]
 [  309   385    41    25   807]
 [  585   385   221   129 22380]]
Norbert Tiborcz
  • 306
  • 2
  • 9