'Why does find_objects give a bunch of Nones and then range of the whole image?

I am trying to find all objects detected in difference of frames, I thougt this would give a list of each area detected in the threshold, but find_objects is giving a bunch of "None"s and a range of the whole image?

...
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
(slice(0, 972, None), slice(0, 1296, None))

Relevant code can be tested from here

import numpy as np
import cv2
from matplotlib import pyplot as plt
import pylab

from scipy import ndimage
import os

for img in os.listdir('.'):
    if img.endswith('.jpg'):
        image = cv2.imread(img)
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        gray_image = cv2.resize(gray_image, (int(gray_image.shape[1]/2), int(gray_image.shape[0]/2) ))
        ret, threshimg = cv2.threshold(gray_image,0,255,cv2.THRESH_BINARY)
        cv2.imshow('opening',threshimg)
        objects = ndimage.find_objects(threshimg)
        for ob in objects:
            print(ob)
        cv2.waitKey(0)                 # Waits forever for user to press any key   
        cv2.destroyAllWindows()


Solution 1:[1]

The scipy.ndimage.find_objects function returns

A list of tuples, with each tuple containing N slices (with N the dimension of the input array). Slices correspond to the minimal parallelepiped that contains the object. If a number is missing, None is returned instead of a slice.

I think in your data, the labels are not starting from 1 (0 is background and ignored by find_objects). The indices of the entries that are not None are the integer values of the objects.

Solution 2:[2]

You can use cv2.connectedComponentsWithStats for the same.

import numpy as np
import cv2
from matplotlib import pyplot as plt
import pylab

from scipy import ndimage
import os
### for visualising connected component image
def imshow_components(labels):
    # Map component labels to hue val
    label_hue = np.uint8(179*labels/np.max(labels))
    blank_ch = 255*np.ones_like(label_hue)
    labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])

    # cvt to BGR for display
    labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)

    # set bg label to black
    labeled_img[label_hue==0] = 0
    return labeled_img

for img in os.listdir('.'):
    if img.endswith('.jpg'):
        image = cv2.imread(img)
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        gray_image = cv2.resize(gray_image, (int(gray_image.shape[1]/2), int(gray_image.shape[0]/2) ))
        ret, threshimg = cv2.threshold(gray_image,0,255,cv2.THRESH_BINARY)
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh)
        out_image=imshow_components(labels)
        #### stats will have x,y,w,h,area of each detected connected component

Refer to this answer for more info on connected component features.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zudi
Solution 2 Sreekiran A R