Python: How to check if an array is contained in another array using `numpy.all`and `numpy.any`?

13.1k views Asked by At

I am working on detecting certain areas on an image using scikit-image. I was able to detect blobs using blob_doh function. Also I was able to find regions using Canny edge detector and labeling.

Now I want to check if the blobs, which I found before, are inside of those regions, and sort out those blobs which are not in any of the regions. Then I want to draw only the blobs which are inside the regions.

I was trying to implement this using numpy.all and numpy.any but I probably misunderstand the way these functions work. Here is what I have:

for region in regions:
    # list of pixels' coords in a region
    pixel_array = region.coords

    # check if a blob is inside the region
    for blob in blobs_doh:
        y, x, r = blob

        if np.any(pixel_array == [x, y]):
            c = plt.Circle((x, y), r, color='red', linewidth=1, fill=False)
            minr, minc, maxr, maxc = region.bbox
            rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='lime', linewidth=1)
            # draw blobs and regtangles
            ax.add_patch(c)
            ax.add_patch(rect)
            break

So, what I do. region is an array of the shape [[a1, b1], [a2, b2], [a3, b3], ..., [an, bn]], and a blob is an array of the shape [c, d]. My idea was to check if there is any sub-array in region equal to blob. I could do it of course in trivial way searching in a loop, but I thought there is more efficient way of doing this, and tried to use numpy.all and numpy.any. Unfortunately, I cannot get it working correctly. The line np.any(pixel_array == [x, y]) checks for only the first element of blob but not for the sub-array [x, y] as a whole. I also tried different combinations of .any and .all using axis argument:

np.any(pixel_array == [x, y], axis = 1).all(axis = 0)

but could not get any acceptable result.

Please help me with this task. What is the better way of performing such a check?

Thank you.

1

There are 1 answers

0
tmdavison On BEST ANSWER

You can do it if you convert pixel_array to a list. Not sure how efficient that would be, but this works:

if [x,y] in pixel_array.tolist():

EDIT:

Looks like someone has already timed lots of different options in this answer. The tolist() solution above isn't too bad, but the best option over a range of scenarios seems to be:

 if any(np.equal(pixel_array,[x,y]).all(1)):