Image skewness kurtosis in python

2024/10/12 0:27:44

Is there a python package that will provide me a way to clacluate Skewness and Kurtosis of an image?. Any example will be great.

Thanks a lot.

Answer

I am assuming that you have an image that shows some kind of peak, and you are interesting in getting the Skewness and Kurtosis (and probably the standard deviation and centroid) of that peak in both the x and y directions.

I was wondering about this as well. Curiously, I did not find this implemented into any of the python image analysis packages. OpenCV has a moments function, and we should be able to get the skewness from these, but the moments only go to 3rd order, and we need 4th order to get kurtosis.

To make things easier and faster, I think that taking the projection of the image in the x and y directions and finding the statistics from these projections is mathematically equivalent to finding the statistics using the full image. In the following code, I use both methods and show that they are the same for this smooth example. Using a real, noisy image, I found that the two methods also provide the same result, but only if you manually cast the image data to float64 (it imported as float 32, and "numerical stuff" caused the results to be slightly different.

Below is an example. You should be able to cut and paste the "image_statistics()" function into your own code. Hopefully it works for someone! :)

import numpy as np
import matplotlib.pyplot as plt
import timeplt.figure(figsize=(10,10))ax1 = plt.subplot(221)
ax2 = plt.subplot(222)
ax4 = plt.subplot(224)#Make some sample data as a sum of two elliptical gaussians:
x = range(200)
y = range(200)X,Y = np.meshgrid(x,y)def twoD_gaussian(X,Y,A=1,xo=100,yo=100,sx=20,sy=10):return A*np.exp(-(X-xo)**2/(2.*sx**2)-(Y-yo)**2/(2.*sy**2))Z = twoD_gaussian(X,Y) + twoD_gaussian(X,Y,A=0.4,yo=75)ax2.imshow(Z) #plot it#calculate projections along the x and y axes for the plots
yp = np.sum(Z,axis=1)
xp = np.sum(Z,axis=0)ax1.plot(yp,np.linspace(0,len(yp),len(yp)))
ax4.plot(np.linspace(0,len(xp),len(xp)),xp)#Here is the business:
def image_statistics(Z):#Input: Z, a 2D array, hopefully containing some sort of peak#Output: cx,cy,sx,sy,skx,sky,kx,ky#cx and cy are the coordinates of the centroid#sx and sy are the stardard deviation in the x and y directions#skx and sky are the skewness in the x and y directions#kx and ky are the Kurtosis in the x and y directions#Note: this is not the excess kurtosis. For a normal distribution#you expect the kurtosis will be 3.0. Just subtract 3 to get the#excess kurtosis.import numpy as nph,w = np.shape(Z)x = range(w)y = range(h)#calculate projections along the x and y axesyp = np.sum(Z,axis=1)xp = np.sum(Z,axis=0)#centroidcx = np.sum(x*xp)/np.sum(xp)cy = np.sum(y*yp)/np.sum(yp)#standard deviationx2 = (x-cx)**2y2 = (y-cy)**2sx = np.sqrt( np.sum(x2*xp)/np.sum(xp) )sy = np.sqrt( np.sum(y2*yp)/np.sum(yp) )#skewnessx3 = (x-cx)**3y3 = (y-cy)**3skx = np.sum(xp*x3)/(np.sum(xp) * sx**3)sky = np.sum(yp*y3)/(np.sum(yp) * sy**3)#Kurtosisx4 = (x-cx)**4y4 = (y-cy)**4kx = np.sum(xp*x4)/(np.sum(xp) * sx**4)ky = np.sum(yp*y4)/(np.sum(yp) * sy**4)return cx,cy,sx,sy,skx,sky,kx,ky#We can check that the result is the same if we use the full 2D data array
def image_statistics_2D(Z):h,w = np.shape(Z)x = range(w)y = range(h)X,Y = np.meshgrid(x,y)#Centroid (mean)cx = np.sum(Z*X)/np.sum(Z)cy = np.sum(Z*Y)/np.sum(Z)###Standard deviationx2 = (range(w) - cx)**2y2 = (range(h) - cy)**2X2,Y2 = np.meshgrid(x2,y2)#Find the variancevx = np.sum(Z*X2)/np.sum(Z)vy = np.sum(Z*Y2)/np.sum(Z)#SD is the sqrt of the variancesx,sy = np.sqrt(vx),np.sqrt(vy)###Skewnessx3 = (range(w) - cx)**3y3 = (range(h) - cy)**3X3,Y3 = np.meshgrid(x3,y3)#Find the thid central momentm3x = np.sum(Z*X3)/np.sum(Z)m3y = np.sum(Z*Y3)/np.sum(Z)#Skewness is the third central moment divided by SD cubedskx = m3x/sx**3sky = m3y/sy**3###Kurtosisx4 = (range(w) - cx)**4y4 = (range(h) - cy)**4X4,Y4 = np.meshgrid(x4,y4)#Find the fourth central momentm4x = np.sum(Z*X4)/np.sum(Z)m4y = np.sum(Z*Y4)/np.sum(Z)#Kurtosis is the fourth central moment divided by SD to the fourth powerkx = m4x/sx**4ky = m4y/sy**4return cx,cy,sx,sy,skx,sky,kx,ky#Calculate the image statistics using the projection method
stats_pr = image_statistics(Z)#Confirm that they are the same by using a 2D calculation
stats_2d = image_statistics_2D(Z)names = ('Centroid x','Centroid y','StdDev x','StdDev y','Skewness x','Skewness y','Kurtosis x','Kurtosis y')print 'Statistis\t1D\t2D'
for name,i1,i2 in zip(names, stats_2d,stats_pr):print '%s \t%.2f \t%.2f'%(name, i1,i2)plt.show()

Screen shot of output, just for fun:

screen shot of output

One more thing: depending on exactly what you are doing with the images, you might consider using ImageJ for your image analysis – but beware! The moments plugin will let you calculate the skewness, kurtosis, etc. ImageJ does have a "skewness" and "kurtosis" in Analyze>>Set Measurements menu, but I think that this actually finds the skewness and kurtosis of the intensity histogram (I was fooled for a minute).

https://en.xdnf.cn/q/69716.html

Related Q&A

Python: Getting all the items out of a `threading.local`

I have a threading.local object. When debugging, I want to get all the objects it contains for all threads, while I am only on one of those threads. How can I do that?

Why tuple is not mutable in Python? [duplicate]

This question already has answers here:Closed 11 years ago.Possible Duplicate:Why are python strings and tuples are made immutable? What lower-level design makes tuple not mutable in Python? Why th…

Display Django form fields on the same line

I would like to display two form fields on the same line and not each one after the other one.For the moment, I get:Choice a theme :. Datasystems. CamerounBut I would like to display this form like:Cho…

How can I use the index array in tensorflow?

If given a matrix a with shape (5,3) and index array b with shape (5,), we can easily get the corresponding vector c through,c = a[np.arange(5), b]However, I cannot do the same thing with tensorflow,a …

cython with array of pointers

I have a list of numpy.ndarrays (with different length) in python and need to have very fast access to those in python. I think an array of pointers would do the trick. I tried:float_type_t* list_of_ar…

How to skip blank lines with read_fwf in pandas?

I use pandas.read_fwf() function in Python pandas 0.19.2 to read a file fwf.txt that has the following content:# Column1 Column2123 abc456 def# #My code is the following:import pandas as pd fil…

Pandas rolling std yields inconsistent results and differs from values.std

Using pandas v1.0.1 and numpy 1.18.1, I want to calculate the rolling mean and std with different window sizes on a time series. In the data I am working with, the values can be constant for some subse…

How to change attributes of a networkx / matplotlib graph drawing?

NetworkX includes functions for drawing a graph using matplotlib. This is an example using the great IPython Notebook (started with ipython3 notebook --pylab inline):Nice, for a start. But how can I in…

Deploying MLflow Model without Conda environment

Currently working on deploying my MLflow Model in a Docker container. The Docker container is set up with all the necessary dependencies for the model so it seems redundant for MLflow to also then crea…

Insert Data to SQL Server Table using pymssql

I am trying to write the data frame into the SQL Server Table. My code:conn = pymssql.connect(host="Dev02", database="DEVDb") cur = conn.cursor() query = "INSERT INTO dbo.SCORE…