How would I find the mode (stats) of pixel values of an image?

北慕城南 提交于 2021-02-16 21:04:56

问题


I'm using opencv and I'm able to get a pixel of an image-- a 3-dimensional tuple, via the code below. However, I'm not quite sure how to calculate the mode of the pixels values in the image.

import cv2
import numpy as np
import matplotlib.pyplot as plt

import numpy as np
import cv2


img =cv2.imread('C:\\Users\Moondra\ABEO.png')

#px = img[100,100]  #gets pixel value
#print (px)

I tried,

from scipy import stats
stats.mode(img)[0]

But this returns an array shape of

stats.mode(img)[0].shape
(1, 800, 3)

Not sure how exactly stats is calculating the dimensions from which to choose the mode, but I'm looking for each pixel value (3 dimensional tuple) to be one element.

EDIT: For clarity, I'm going to lay out exactly what I'm looking for. Let's say we have an array that is of shape (3,5,3) and looks like this

array([[[1, 1, 2],    #[1,1,2] = represents the RGB values
        [2, 2, 2],
        [1, 2, 2],
        [2, 1, 1],
        [1, 2, 2]],

       [[1, 2, 2],
        [2, 2, 2],
        [2, 2, 2],
        [1, 2, 2],
        [1, 2, 1]],

       [[2, 2, 1],
        [2, 2, 1],
        [1, 1, 2],
        [2, 1, 2],
        [1, 1, 2]]])

I would then convert it to an array that looks like this for easier calculation

Turn this into

array([[1, 1, 2],
         [2, 2, 2],
         [1, 2, 2],
        [2, 1, 1],
        [1, 2, 2],

       [1, 2, 2],
        [2, 2, 2],
        [2, 2, 2],
        [1, 2, 2],
        [1, 2, 1],

       [2, 2, 1],
        [2, 2, 1],
        [1, 1, 2],
        [2, 1, 2],
        [1, 1, 2]])


which is of shape(15,3)

I would like to calculate the mode by counting each set of RGB as follows:

 [1,1,2] = 3
 [2,2,2] = 4  
[1,2,2] = 4
[2,1,1] = 2
[1,1,2] =1

Thank you.


回答1:


From the description, it seems you are after the pixel that's occurring the most in the input image. To solve for the same, here's one efficient approach using the concept of views -

def get_row_view(a):
    void_dt = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[-1])))
    a = np.ascontiguousarray(a)
    return a.reshape(-1, a.shape[-1]).view(void_dt).ravel()

def get_mode(img):
    unq, idx, count = np.unique(get_row_view(img), return_index=1, return_counts=1)
    return img.reshape(-1,img.shape[-1])[idx[count.argmax()]]

We can also make use of np.unique with its axis argument, like so -

def get_mode(img):
    unq,count = np.unique(img.reshape(-1,img.shape[-1]), axis=0, return_counts=True)
    return unq[count.argmax()]

Sample run -

In [69]: img = np.random.randint(0,255,(4,5,3))

In [70]: img.reshape(-1,3)[np.random.choice(20,10,replace=0)] = 120

In [71]: img
Out[71]: 
array([[[120, 120, 120],
        [ 79, 105, 218],
        [ 16,  55, 239],
        [120, 120, 120],
        [239,  95, 209]],

       [[241,  18, 221],
        [202, 185, 142],
        [  7,  47, 161],
        [120, 120, 120],
        [120, 120, 120]],

       [[120, 120, 120],
        [ 62,  41, 157],
        [120, 120, 120],
        [120, 120, 120],
        [120, 120, 120]],

       [[120, 120, 120],
        [  0, 107,  34],
        [  9,  83, 183],
        [120, 120, 120],
        [ 43, 121, 154]]])

In [74]: get_mode(img)
Out[74]: array([120, 120, 120])


来源:https://stackoverflow.com/questions/43826089/how-would-i-find-the-mode-stats-of-pixel-values-of-an-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!