0

I have an image represented as a uint16 numpy array (orig_arr) with a skewed distribution. I would like to create a new array (noise_arr) of random values, but that matches the mean and standard deviation of orig_img.

I believe this will require two main steps:

  1. Measure the mean and distribution of orig_arr
  2. Create a new array of random values using the mean and distribution measured in step 1

I'm pretty much lost on how to do this, but here's a sample image and a bit of code to get you started:

Sample image: https://drive.google.com/open?id=1bevwW-NHshIVRqni5O62QB7bxcxnUier (looks blank but it's not)

orig_arr = cv2.imread('sample_img.tif', -1)
orig_mean = np.mean(orig_arr)
orig_sd = np.std(orig_arr)

print(orig_mean)
18.676384933578962

print(orig_sd)    
41.67964688299941
holastello
  • 593
  • 1
  • 7
  • 16
  • Probably need to see the distribution of your original image as the second step to decide which family to sample from in step 3. – josemz Feb 08 '19 at 23:09

1 Answers1

1

I think scipy.stats.skewnorm might do the trick. It lets you characterize skewed normal distributions, and also sample data from skewed normal distributions.

Now... maybe that's a bad assumption for your data... maybe it's not skew-normal, but this is the first thing I'd try.

# import skewnorm
from scipy.stats import skewnorm

# find params
a, loc, scale = skewnorm.fit(orig_arr)

# mimick orig distribution with skewnorm
# keep size and shape the same as orig_arr
noise_arr = skewnorm(a, loc, scale).rvs(orig_arr.size).astype('uint16').reshape(orig_array.shape)

There's more detail about exploring this kind of data... plotting it... comparing it... over here: How to create uint16 gaussian noise image?

Also... I think using imshow and setting vmin and vmax will let you look at an image or heatmap of your data that is sensitive to the range. That is demonstrated in the link above as well.

Hope that helps!

kmh
  • 1,516
  • 17
  • 33