0

I have an Numpy array (it's the red channel from an image).

I have masked a portion of it (making those values 0), and now I would like to find the Mode of the values in my non masked area.

The problem I'm running into is that the Mode command keeps coming back with [0]. I want to exclude the 0 values (the masked area), but I'm not sure how to do this?

This is the command I was using to try and get mode:

#mR is the Numpy Array of the Red channel with the values of the areas I don't want at 0


print(stats.mode(mR[:, :], axis=None))

Returns 0 as my Mode. How do I exclude 0 or the masked area?

Update - Full Code:

Here's my full code using the "face" from scipy.misc - still seems slow with that image and the result is "107" which is way to high for the masked area (shadows) so seems like it's processing the whole image, not just the area in the mask.


import cv2
import numpy as np
from scipy import stats
import scipy.misc


img = scipy.misc.face()

img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
r, g, b = cv2.split(img_rgb)


img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l_channel ,a_channel, b_channel = cv2.split(img_lab)


mask = cv2.inRange(l_channel, 5, 10)
cv2.imshow("mask", mask)


print(stats.mode(r[mask],axis=None))


cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)

2 Answers2

2

You can just mask the array and use np.histogram:

counts, bins = np.histogram(mR[mR>0], bins=np.arange(256))

# mode
modeR = np.argmax(counts)
Quang Hoang
  • 146,074
  • 10
  • 56
  • 74
0

Update:

After the OP kindly posted their full code, I can confirm that stats.mode() is either extremely slow or never in fact completes (who knows why?).

On the other hand @Quang Hoang's solution is as elegant as it is fast - and it also works for me in terms of respecting the mask.

I of course therefore throw my weight behind QH's answer.

My old answer:

Try

print(stats.mode(mR[mask],axis=None))

Except for the masking, calculating the mode of a numpy array efficiently is covered extensively here:

Most efficient way to find mode in numpy array

jtlz2
  • 7,700
  • 9
  • 64
  • 114
  • 2
    yeah adding [mask] works - but it runs incredibly slow. And noticing it's not giving me a valid value (shows as 233) no mater what my mask is, when the value should be pretty slow (20's or 30's)... seems like it isn't respecting the mask. – CreativelyChris Apr 26 '20 at 04:18
  • How are you generating your mask? What are the array dimensions – jtlz2 Apr 26 '20 at 11:03