How to detect foreign objects on a plane?

asked 2020-04-13 01:30:06 -0500

prostoi chelovek gravatar image

updated 2020-04-13 02:08:21 -0500

My task is to detect whether table clean or not. My current method is to do some kind of shadow removal using algorithm given in a SO answer:

    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    dilated_img = cv2.dilate(img_gray, np.ones((7, 7), np.uint8))
    bg_img = cv2.medianBlur(dilated_img, 21)
    diff_img = 255 - cv2.absdiff(img_gray, bg_img)
    norm_img = cv2.normalize(diff_img, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

and it gives the following result: image descriptionimage description
after that I am performing a background subtraction using MOG2 and some morphology:

    opening_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
    closing_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    erode_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

    res = cv2.morphologyEx(mask, cv2.MORPH_OPEN, opening_kernel)
    res = cv2.erode(res, erode_kernel)
    res = cv2.morphologyEx(res, cv2.MORPH_CLOSE, closing_kernel)

and the final mask looks like image description
while the foreground mask is image description
This method kind of works and successfully detects objects, and moreover, it is invariant to shadows(sometimes), but sometimes this algorithms gives a lot of false positives without an obvious reason. I think, that the problem is in the "shadow removal" because the result looks very strange. I know, that the shadow removal task itself is a very complex and i don`t think, that I need an actual shadow removal, but my program may work outside or in places with unstable lightning conditions and it is important to minimize probability of the false positives. I also think, that my morphology part is not good, but i can`t understand, how to do it properly.
Is there a better way to make my program shadow-invariant without high computing costs (because it will be running on a raspberry pi)?
And, maybe there is a better way to accomplish my goal in general?
Thank you! and sorry for such an unstructured question

edit retag flag offensive close merge delete


Do you really need to make your observation from only one image, or can you first take an "empty" reference image and make comparisons with that? Your life would be so much easier and foreground/background subtractors would be your your keyword. My appologiez if I'm off with the suggestion to use another method. But in case that is an option, this would be my first suggestion as the way to go.

noshky gravatar imagenoshky ( 2020-04-26 15:13:58 -0500 )edit