diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_10_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_10_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..2f0d626 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_10_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_11_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_11_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..8c2f52e Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_11_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_12_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_12_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..6143dc0 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_12_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_13_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_13_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..da75b1f Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_13_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_14_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_14_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..6cff84f Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_14_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_15_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_15_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..4ed6fc8 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_15_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_16_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_16_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..073c075 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_16_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_17_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_17_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..4adf3d8 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_17_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_18_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_18_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..07000f1 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_18_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_19_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_19_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..db6b4ec Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_19_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_1_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_1_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..d0ef117 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_1_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_20_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_20_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..31f781e Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_20_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_21_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_21_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..30fdbc6 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_21_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_22_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_22_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..4445fbc Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_22_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_23_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_23_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..a09504c Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_23_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_24_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_24_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..e71a02f Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_24_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_25_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_25_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..1304d21 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_25_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_26_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_26_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..13f0e71 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_26_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_27_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_27_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..f292047 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_27_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_28_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_28_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..e4fae44 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_28_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_29_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_29_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..a37273d Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_29_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_2_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_2_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..d63c49a Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_2_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_30_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_30_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..b2c9909 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_30_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_31_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_31_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..7c540eb Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_31_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_3_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_3_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..8bf63f9 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_3_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_4_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_4_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..6920946 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_4_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_5_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_5_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..7d2b9da Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_5_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_6_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_6_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..e8760d5 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_6_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_7_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_7_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..c167201 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_7_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_8_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_8_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..f42abd0 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_8_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_9_GaussianNorm_75StdDev.tif b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_9_GaussianNorm_75StdDev.tif new file mode 100644 index 0000000..71b1d04 Binary files /dev/null and b/SpeckleSizeCode/MATLAB/20190924-200ms_20mW_Ave15_Gray_10X0.4_9_GaussianNorm_75StdDev.tif differ diff --git a/SpeckleSizeCode/PythonAutocorr/autocorr.py b/SpeckleSizeCode/PythonAutocorr/autocorr.py new file mode 100644 index 0000000..346e218 --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/autocorr.py @@ -0,0 +1,108 @@ +import numpy as np +import matplotlib.pyplot as plt +import tifffile +import os +from scipy.ndimage import gaussian_filter +import cv2 + +nb = 13 +fname = rf"20190924-200ms_20mW_Ave15_Gray_10X0.4_{nb}.tif" + +p = os.path.dirname(os.path.join(os.getcwd(), "..", "..")) +path = os.path.join(p, "MATLAB", fname) + +prefix = "circularWithPhasesSimulations" +otherPrefix = "50sims" +path = "4pixelsCircularWithPhasesSimulations.tiff" +args = [prefix, path] +#args = [prefix, otherPrefix, path] +path = os.path.join(*args) + +if path.endswith("tif") or path.endswith("tiff"): + img = tifffile.imread(path) +else: + img = cv2.imread(path) + +plt.imshow(img) +plt.show() + +imgDivide = gaussian_filter(img, 75) + +img = img / imgDivide - np.mean(img) +plt.imshow(img) +plt.show() + +fft = np.fft.fft2(img) +ifft = np.fft.ifftshift(np.fft.ifft2(np.abs(fft) ** 2)).real +ifft /= np.size(ifft) + +r = (ifft - np.mean(img) ** 2) / np.var(img) +plt.imshow(r) +plt.colorbar() +plt.show() + +xSlice, ySlice = r.shape[1] // 2, r.shape[0] // 2 + +verticalSlice = r[:, xSlice] +horizontalSlice = r[ySlice, :] + + +def normalize(verticalSlice, horizontalSlice): + verticalSlice = verticalSlice - np.min(verticalSlice) + verticalSlice = verticalSlice / np.max(verticalSlice) + + horizontalSlice = horizontalSlice - np.min(horizontalSlice) + horizontalSlice = horizontalSlice / np.max(horizontalSlice) + return verticalSlice, horizontalSlice + + +plt.plot(verticalSlice) +plt.title("Autocorrelation profile (x centered)") +plt.xlabel("Vertical position y [px]") +plt.ylabel("Normalized correlation coefficient [-]") +plt.show() + +plt.plot(horizontalSlice) +plt.title("Autocorrelation profile (y centered)") +plt.xlabel("Horizontal position x [px]") +plt.ylabel("Normalized correlation coefficient [-]") +plt.show() + +relativeErrorHalfMax = 25 + +# Y FWHM +print("Y FWHM") +halfMax = 0.5 +inferiorBound = halfMax - halfMax * relativeErrorHalfMax / 100 +superiorBound = halfMax + halfMax * relativeErrorHalfMax / 100 + +# Range of values to compute FWHM +pointsForFW = np.where((verticalSlice >= inferiorBound) & (verticalSlice <= superiorBound))[0] +print(pointsForFW) +middlePoint = np.argmax(verticalSlice) # Find the middle point to separate the values at the left and at the right +left = np.mean(pointsForFW[pointsForFW < middlePoint]) +right = np.mean(pointsForFW[pointsForFW > middlePoint]) +print(f"left: {left}") +print(f"right: {right}") +FWHM = right - left +print("Diameter : ", FWHM) +print("Radius : ", FWHM / 2) + +# X FWHM +print("= = = = = = = = = = = = = = = = = = = = = = = =") +print("X FWHM") +halfMax = 0.5 +inferiorBound = halfMax - halfMax * relativeErrorHalfMax / 100 +superiorBound = halfMax + halfMax * relativeErrorHalfMax / 100 + +# Range of values to compute FWHM +pointsForFW = np.where((horizontalSlice >= inferiorBound) & (horizontalSlice <= superiorBound))[0] +print(pointsForFW) +middlePoint = np.argmax(horizontalSlice) # Find the middle point to separate the values at the left and at the right +left = np.mean(pointsForFW[pointsForFW < middlePoint]) +right = np.mean(pointsForFW[pointsForFW > middlePoint]) +print(f"left: {left}") +print(f"right: {right}") +FWHM = right - left +print("Diameter : ", FWHM) +print("Radius : ", FWHM / 2) diff --git a/SpeckleSizeCode/PythonAutocorr/autocorrelation.py b/SpeckleSizeCode/PythonAutocorr/autocorrelation.py new file mode 100644 index 0000000..3619cfe --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/autocorrelation.py @@ -0,0 +1,132 @@ +import numpy as np +import matplotlib.pyplot as plt +import tifffile +from scipy.ndimage import gaussian_filter, median_filter +from scipy.signal import correlate2d +import cv2 + + +class FileReader: + # FIXME: This is only until pydcclab is ok + + @staticmethod + def readFile(path: str): + if path.endswith(".tif") or path.endswith(".tiff"): + pixels = tifffile.imread(path) + else: + pixels = cv2.imread(path) + return pixels.T # we want shape[0] as the width and shape[1] as the height + + +class Autocorrelation: + # FIXME: Use pydcclab when ok + + def __init__(self, imagePath: str): + self.__image = FileReader.readFile(imagePath) + self.__original = self.image + self.__autocorrelation = None + self.__slicesObj = None + + @property + def image(self): + return self.__image.copy() + + @property + def autocorrelation(self): + if self.__autocorrelation is None: + return None + return self.__autocorrelation.copy() + + def getSlices(self, indices: tuple = None): + if self.__slicesObj is None: + raise ValueError("Please compute the autocorrelation to access its slices.") + if indices is None: + return self.__slicesObj.middleSlices() + return self.__slicesObj.slicesAt(indices) + + def computeAutocorrelation(self, gaussianFilterStdDev: float = 75, medianFilterSize: int = 3): + self._gaussianNormalization(gaussianFilterStdDev) # First, gaussian filter normalization + self._medianFilter(medianFilterSize) # Then, median filter to remove noise + self._autocorrelationWithFourierTransform() # Compute the autocorrelation + + def _gaussianNormalization(self, filterStdDev: float = 75): + filteredImage = gaussian_filter(self.__image, filterStdDev) + self.__image = self.__image / filteredImage - np.mean(self.__image) + + def _autocorrelationWithFourierTransform(self): + fft = np.fft.fft2(self.__image) + ifft = np.fft.ifftshift(np.fft.ifft2(np.abs(fft) ** 2)).real + ifft /= np.size(ifft) + self.__autocorrelation = (ifft - np.mean(self.__image) ** 2) / np.var(self.__image) + self.__slicesObj = AutocorrelationSlices(self.__autocorrelation) + + + def _medianFilter(self, filterSize: int = 3): + self.__image = median_filter(self.__image, filterSize) + + def showImage(self): + plt.imshow(self.__image) + plt.show() + + def showAutocorrelation(self, showColorbar: bool = True): + if self.__autocorrelation is None: + raise ValueError("No autocorrelation computed.") + plt.imshow(self.__autocorrelation) + if showColorbar: + plt.colorbar() + plt.show() + + def showAutocorrelationSlices(self, indices: tuple = None, showHorizontal: bool = True, showVertical: bool = True): + vSlice, hSlice = self.getSlices(indices) + if showHorizontal and showVertical: + fig, (ax1, ax2) = plt.subplots(2, sharey="col") + fig.suptitle("Autocorrelation slices") + + ax1.plot(hSlice) + ax1.set_title(f"Horizontal slice (at index {indices[0]})") + ax1.set_xlabel("Horizontal position $x$ [pixel]") + + ax2.plot(vSlice) + ax1.set_title(f"Vertical slice (at index {indices[1]})") + ax1.set_xlabel("Vertical position $y$ [pixel]") + + ylabel = "Normalized autocorrelation coefficient [-]" + fig.text(0.06, 0.5, ylabel, ha='center', va='center', rotation='vertical') + plt.subplots_adjust(hspace=0.32) + plt.show() + elif showVertical: + plt.plot(vSlice) + plt.title(f"Vertical slice (at index {indices[1]})") + plt.xlabel("Vertical position $y$ [pixel]") + plt.ylabel("Normalized autocorrelation coefficient [-]") + plt.show() + elif showHorizontal: + plt.plot(hSlice) + plt.title(f"Horizontal slice (at index {indices[0]})") + plt.xlabel("Horizontal position $x$ [pixel]") + plt.ylabel("Normalized autocorrelation coefficient [-]") + plt.show() + + +class AutocorrelationSlices: + + def __init__(self, autocorrelation: np.ndarray): + if not isinstance(autocorrelation, np.ndarray): + raise TypeError("The autocorrelation parameter must be a numpy array.") + if not autocorrelation.ndim == 2: + raise ValueError("The autocorrelation must be in 2D.") + self.__autocorrelation = autocorrelation + + def slicesAt(self, indices: tuple): + if len(indices) != 2: + raise ValueError("There must be 2 indices of slicing, one horizontal and one vertical.") + # Assumes indices[0] is the width and indices[1] is the height + xSlice, ySlice = indices[0], indices[1] + verticalSlice = self.__autocorrelation[:, ySlice] + horizontalSlice = self.__autocorrelation[xSlice, :] + return verticalSlice, horizontalSlice + + def middleSlices(self): + # Assumes the shape of the autocorrelation is (width, height) or (nb columns, nb lines) + middleX, middleY = self.__autocorrelation.shape[0] // 2, self.__autocorrelation.shape[1] // 2 + return self.slicesAt((middleX, middleY)) diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/10pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/10pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..3eadf9e Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/10pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/12pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/12pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..3794804 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/12pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/14pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/14pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..511ff09 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/14pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/16pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/16pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..b16e034 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/16pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/18pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/18pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..8140b9d Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/18pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/20pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/20pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..f6ef3ef Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/20pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/22pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/22pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..e63f4d0 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/22pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/24pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/24pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..200f35f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/24pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/32pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/32pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..044db8c Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/32pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/4pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/4pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..f227c0e Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/4pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/6pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/6pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..7caae43 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/6pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/8pixelsCircularWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/8pixelsCircularWithPhasesSimulations.tiff new file mode 100644 index 0000000..28a8cc1 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/circularWithPhasesSimulations/8pixelsCircularWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianNormalization.py b/SpeckleSizeCode/PythonAutocorr/gaussianNormalization.py new file mode 100644 index 0000000..59fb51b --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/gaussianNormalization.py @@ -0,0 +1,61 @@ +import tifffile +from scipy.ndimage import gaussian_filter +import numpy as np +import cv2 +import os + + +class GaussianNormalization: + + def __init__(self, image: np.ndarray): + self.image = image + self.normalized = None + + def normalize(self, stdDev: float): + gaussianFiltered = gaussian_filter(self.image, stdDev) + self.normalized = self.image / gaussianFiltered - np.mean(self.image) + + def saveToOriginalFormat(self, name: str, stdDevNormalization: float = 75): + raise NotImplementedError("You must implement this method in format-specific classes.") + + +class TiffFileGaussianNormalization(GaussianNormalization): + + def __init__(self, path: str): + image = tifffile.imread(path) + super(TiffFileGaussianNormalization, self).__init__(image) + + def saveToOriginalFormat(self, name: str, stdDevNormalization: float = 75): + if self.normalized is None: + self.normalize(stdDevNormalization) + if not name.endswith(".tif") and not name.endswith(".tiff"): + name += ".tif" + tifffile.imwrite(name, self.image) + + +class PNGFileGaussianNormalization(GaussianNormalization): + + def __init__(self, path: str): + image = cv2.imread(path) + super(PNGFileGaussianNormalization, self).__init__(image) + + def saveToOriginalFormat(self, name: str, stdDevNormalization: float = 75): + if self.normalized is None: + self.normalize(stdDevNormalization) + if not name.endswith(".png"): + name += ".png" + cv2.imwrite(name, self.image) + + +if __name__ == '__main__': + # This is where you can normalize and save files. + # This is an example that normalizes avery tif file in MATLAB folder. + for nb in range(1, 32): + fname = r"20190924-200ms_20mW_Ave15_Gray_10X0.4_{}.tif".format(nb) + p = os.path.dirname(os.path.join(os.getcwd(), "..", "..")) + path = os.path.join(p, "MATLAB", fname) + newName = path[:-4] + "_GaussianNorm_75StdDev.tif" # We don't want the previous .tif in the new name + + tif = TiffFileGaussianNormalization(path) + tif.saveToOriginalFormat(newName) + print(f"{nb} / 31 processed") diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..0812c3f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..1af26e3 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/10sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..51820ee Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..b5fe4aa Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/12sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..e123275 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..a64d9e4 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/14sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..57c728f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..600c532 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/16sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..f4b3ee8 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..7ec3d76 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/18sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..56599c6 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..b9a1ca7 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/20sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..45e1cb2 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..74504a8 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/22sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..d52ea6f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..0885bdb Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/24sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..b3e9c51 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..12a8532 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/32sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..6ba7688 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..2e04a30 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/4sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..28d620e Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..aaf5b10 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/6sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations.tiff new file mode 100644 index 0000000..1f45d1d Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations_cut1overE.tiff b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations_cut1overE.tiff new file mode 100644 index 0000000..682eadf Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/gaussianWithPhasesSimulations/8sigmaGaussianWithPhasesSimulations_cut1overE.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/peakMeasurement.py b/SpeckleSizeCode/PythonAutocorr/peakMeasurement.py new file mode 100644 index 0000000..df1af54 --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/peakMeasurement.py @@ -0,0 +1,155 @@ +import numpy as np +import math +import warnings + + +class HalfWidthAtHalfMaximumOneDimension: + + def __init__(self, data: np.ndarray, maximum: float = None, positiveSlopeSideOfPeak: bool = None): + # If no maximum is provided, taking the maximal value of data. Else, taking the provided one. + # if positiveSlopeSideOfPeak is not None: assumes there is only half of the central peak, either the increasing + # side (arg is True) or the decreasing one (arg is False). + # Else, the algorithm takes the left left side of the peak. + if maximum is None: + maximum = np.max(data) + self.maximum = maximum + if positiveSlopeSideOfPeak is None: + data = data[:np.argmax(data)] + positiveSlopeSideOfPeak = True + if not isinstance(data, np.ndarray): + raise TypeError("The data must be within a numpy array.") + if data.ndim != 1: + raise ValueError("The data must be in one dimension.") + self._data = data + self._sideOfPeak = "left" if positiveSlopeSideOfPeak else "right" + self.HWHM = None + self.report = None + + def findHWHM(self): + raise NotImplementedError("This method must be implemented by subclasses.") + + +class HalfWidthAtHalfMaximumNeighborsAveraging(HalfWidthAtHalfMaximumOneDimension): + + def __init__(self, data: np.ndarray, maximum: float = None, positiveSlopeSideOfPeak: bool = None, + errorRange: float = 20 / 100): + self.__error = errorRange + self.__dataUsed = None + super(HalfWidthAtHalfMaximumNeighborsAveraging, self).__init__(data, maximum, positiveSlopeSideOfPeak) + + def findHWHM(self): + if self.HWHM is not None: + msg = "The half width at half maximum is already computed. You can access it with the attribute 'HWHM'." + warnings.warn(msg, UserWarning) + return self.HWHM + error = self.__error + halfMax = self.maximum / 2 + inferiorBound = halfMax - halfMax * error + superiorBound = halfMax + halfMax * error + pointsForHWHM = np.where((self._data >= inferiorBound) & (self._data <= superiorBound))[0] + nbPoints = len(pointsForHWHM) + if nbPoints == 0: + raise ValueError("The error is too small. Not enough values were found to compute the HWHM.") + mean = np.mean(pointsForHWHM) + left = 0 + right = mean + if self._sideOfPeak == "left": + left = mean + right = len(self._data) + HWHM = right - left + self.HWHM = HWHM + self.__dataUsed = pointsForHWHM + return HWHM + + +class HalfWidthAtHalfMaximumLinearFit(HalfWidthAtHalfMaximumOneDimension): + + def __init__(self, data: np.ndarray, maximum: float = None, positiveSlopeSideOfPeak: bool = None, + maxNumberOfPoints: int = 10, moreInUpperPart: bool = True): + self.__maxNbPts = maxNumberOfPoints + self.__dataUsed = None + self.__moreInUpperPart = moreInUpperPart + self.__fitInfo = None + super(HalfWidthAtHalfMaximumLinearFit, self).__init__(data, maximum, positiveSlopeSideOfPeak) + + def findHWHM(self): + if self.HWHM is not None: + msg = "The half width at half maximum is already computed. You can access it with the attribute 'HWHM'." + warnings.warn(msg, UserWarning) + return self.HWHM + maxNbPoints = self.__maxNbPts + moreInUpperPart = self.__moreInUpperPart + if maxNbPoints < 2: + raise ValueError("There should be at least 2 points for the linear fit.") + halfMax = self.maximum / 2 + halfK = maxNbPoints / 2 + upperKs = math.ceil(halfK) + lowerKs = math.floor(halfK) + if not moreInUpperPart: + temp = upperKs + upperKs = lowerKs + lowerKs = temp + lows, highs, lIndices, hIndices = splitInTwoWithMiddleValue(halfMax, self._data, True) + lows = lows[:lowerKs] + highs = highs[-upperKs:] + lIndices = lIndices[:lowerKs] + hIndices = hIndices[-upperKs:] + if self._sideOfPeak == "left": + lows = lows[-lowerKs:] + highs = highs[:upperKs] + lIndices = lIndices[-lowerKs:] + hIndices = hIndices[:upperKs] + xData = np.append(lIndices, hIndices) + yData = np.append(lows, highs) + (slope, zero), covMat = np.polyfit(xData, yData, 1, full=False, + cov=True) + left = findXWithY(halfMax, slope, zero) + right = len(self._data) + if self._sideOfPeak == "right": + right = findXWithY(halfMax, slope, zero) + left = 0 + HWHM = right - left + self.HWHM = HWHM + self.__dataUsed = (lows, highs, lIndices, hIndices) + self.__fitInfo = (slope, zero, covMat) + return HWHM + + +class FullWidthAtHalfMaximumNeighborsAveraging(HalfWidthAtHalfMaximumNeighborsAveraging): + + def __init__(self, data: np.ndarray, maximum: float = None, errorRange: float = 20 / 100): + self.FWHM = None + super(FullWidthAtHalfMaximumNeighborsAveraging, self).__init__(data, maximum, errorRange=errorRange) + + def findFWHM(self): + self.FWHM = self.findHWHM() * 2 + return self.FWHM + + +class FullWidthAtHalfMaximumLinearFit(HalfWidthAtHalfMaximumLinearFit): + def __init__(self, data: np.ndarray, maximum: float = None, maximumNumberOfPoints: int = 10, + moreInUpperPart: bool = True): + self.FWHM = None + super(FullWidthAtHalfMaximumLinearFit, self).__init__(data, maximum, None, maximumNumberOfPoints, + moreInUpperPart) + + def findFWHM(self): + self.FWHM = self.findHWHM() * 2 + return self.FWHM + + +def splitInTwoWithMiddleValue(middleValue: float, array: np.ndarray, returnIndices: bool = False): + # Assumes the values are only increasing or decreasing, not both. + # Excludes the middle value + upper = np.ravel(np.where(array > middleValue)) # Doesn't change anything since 1D data + lower = np.ravel(np.where(array < middleValue)) # Doesn't change anything since 1D data + lowerValues = array[lower] + upperValues = array[upper] + if not returnIndices: + return lowerValues, upperValues + return lowerValues, upperValues, lower, upper + + +def findXWithY(y, slope, zero): + x = (y - zero) / slope + return x diff --git a/SpeckleSizeCode/PythonAutocorr/sourceSimulations.py b/SpeckleSizeCode/PythonAutocorr/sourceSimulations.py new file mode 100644 index 0000000..05e9f60 --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/sourceSimulations.py @@ -0,0 +1,234 @@ +import numpy as np +import dcclab as dcc +import tifffile as tfile +import matplotlib.pyplot as plt +import time +from cv2 import cv2 + + +class FullyDeveloppedSpeckleSimulationWithSource: + + def __init__(self, simShape: int): + self._simShape = simShape + self._simulation = None + + @property + def simulation(self): + if self._simulation is None: + return None + return self._simulation.copy() + + def saveSimulation(self, path: str): + sim = self._simulation + if sim is None: + raise ValueError("No simulation to save.") + tfile.imwrite(path, sim) + + def showSimulation(self): + sim = self.simulation + if sim is None: + raise ValueError("No simulation to show.") + plt.imshow(sim, "gray") + plt.show() + + def generatePhases(self, lowerBound: float, upperBound: float): + phases = np.random.uniform(lowerBound, upperBound, (self._simShape, self._simShape)) + return np.exp(1j * phases) + + def runSimulation(self): + raise NotImplementedError("You must implement this abstract method in subclasses.") + + def intensityHistogram(self): + sim = self.simulation + if sim is None: + raise ValueError("No simulation to extract intensity histogram.") + values, binEdges, _ = plt.hist(sim.ravel(), 256) + plt.show() + return values, + + def applyShotNoise(self): + self._simulation = np.random.poisson(self._simulation) + + + def addShotNoise(self,scaling=2,resize=False): + self._simulation = self._simulation * 255 + self._simulation = self._simulation.astype(np.uint8) + simbase = self._simulation + if resize != False: + self._simulation = cv2.resize(self._simulation,resize) + x,y = self._simulation.shape + if scaling >= -2: + self._simulation = self._simulation * (1 + ((scaling - 2) * 0.25)) + arraybefore = self._simulation.astype(np.int16) + self.applyShotNoise() + arrayafter = self._simulation.astype(np.int16) + diff = arrayafter - arraybefore + transfo = simbase.astype(np.int16) + final = np.clip(transfo + diff,0,255) + self._simulation = final.astype(np.uint8) + else: + raise ValueError("scaling value out of range: the scaling values have to be higher than -2") + + def supergaussian(self,center,pos,n,sigmax,sigmay,a=1): + return a * np.exp((-2 * ((pos[0] - center[0]) / sigmax)**n) + (-2 * ((pos[1] - center[1]) / sigmay)**n)) + + def nonUniformIntensity(self,n=4,sigmax=250,sigmay=250): + if n % 2 != 0 or n < 2 : + raise ValueError("n value can only be a positive and even number") + i,j = self._simulation.shape + center = (i // 2, j // 2) + for xval in range(i): + for yval in range(j): + self._simulation[xval,yval] = self._simulation[xval,yval] * self.supergaussian(center,(xval,yval),n,sigmax,sigmay) + + + +class FullyDeveloppedSpeckleSimulationWithCircularSource(FullyDeveloppedSpeckleSimulationWithSource): + + def __init__(self, simShape: int, circleDiameter: float): + super(FullyDeveloppedSpeckleSimulationWithCircularSource, self).__init__(simShape) + if circleDiameter <= 0: + raise ValueError("The diameter must strictly positive (>0).") + self.__radius = circleDiameter / 2 + + def runSimulation(self): + XY = np.indices((self._simShape, self._simShape)) + XY -= self._simShape // 2 + mask = dcc.Channel.createCircularMask(XY, self.__radius) + simulationBefforeFFT = mask * self.generatePhases(-np.pi, np.pi) + simulation = np.abs(np.fft.fftshift(np.fft.fft2(simulationBefforeFFT))) ** 2 + self._simulation = simulation.real + self._simulation /= np.max(self._simulation) + self._simulation = self._simulation.astype(np.float32) + + +class FullyDeveloppedSpeckleSimulationWithGaussianSource(FullyDeveloppedSpeckleSimulationWithSource): + + def __init__(self, simShape: int, gaussian2Sigma: float): + super(FullyDeveloppedSpeckleSimulationWithGaussianSource, self).__init__(simShape) + if gaussian2Sigma <= 0: + raise ValueError("The gaussian standard deviation must be strictly positive (>0).") + self.__sigma = gaussian2Sigma // 2 + + def runSimulation(self): + XY = np.indices((self._simShape, self._simShape)) + XY -= self._simShape // 2 + mask = dcc.Channel.createGaussianMask(XY, self.__sigma) + simulationBefforeFFT = mask * self.generatePhases(-np.pi, np.pi) + simulation = np.abs(np.fft.fftshift(np.fft.fft2(simulationBefforeFFT))) ** 2 + self._simulation = simulation.real + self._simulation /= np.max(self._simulation) + self._simulation = self._simulation.astype(np.float32) + + +class SumOfFullyDeveloppedSpecklesSimulationWithSource: + # FIXME: Use ImageCollection, but need to be fixed first + # FIXME: Implement addition, subtraction, etc. of Channel instances + + def __init__(self, simShape: int, nbOfSimulations: int): + self._simShape = simShape + if nbOfSimulations <= 0: + raise ValueError("There must be at least one simulation to do.") + self._nbSimulation = nbOfSimulations + self.__allSims = None + self.__progress = 0 + + def __runSimulations_iterative(self, array: np.ndarray, simulationClass: type, classArg): + for i in range(self._nbSimulation): + obj = simulationClass(self._simShape, classArg) + obj.runSimulation() + sim = obj.simulation + array[:, :, i] = sim + self.__progress += 1 + if self.__progress % 10 == 0 or self.__progress == self._nbSimulation: + print(f"All simulations: {self.__progress} / {self._nbSimulation} done,") + + def __runSimulations(self, slice_array, simulationClass: type, classArg): + obj = simulationClass(self._simShape, classArg) + obj.runSimulation() + sim = obj.simulation + self.__progress += 1 + if self.__progress % 10 == 0 or self.__progress == self._nbSimulation: + print(f"All simulations: {self.__progress} / {self._nbSimulation} done,") + return sim.ravel() + + def runSimulationsWithCircularSources(self, circleDiameter: float): + start = time.perf_counter_ns() + # self.__allSims = np.zeros((self._simShape * self._simShape, self._nbSimulation)) + # self.__allSims = np.apply_along_axis(self.__runSimulations, 0, self.__allSims, + # FullyDeveloppedSpeckleSimulationWithCircularSource, + # circleDiameter).reshape( + # (self._simShape, self._simShape, self._nbSimulation)) + self.__allSims = np.zeros((self._simShape, self._simShape, self._nbSimulation)) + self.__runSimulations_iterative(self.__allSims, FullyDeveloppedSpeckleSimulationWithCircularSource, + circleDiameter) + end = time.perf_counter_ns() + print(f"Time: {(end - start) / 1e9} seconds") + + def runSimulationsWithGaussianSources(self, sigma: float): + self.__allSims = np.zeros((self._simShape * self._simShape, self._nbSimulation)) + self.__allSims = np.apply_along_axis(self.__runSimulations, 0, self.__allSims, + FullyDeveloppedSpeckleSimulationWithGaussianSource, + sigma).reshape((self._simShape, self._simShape, self._nbSimulation)) + + @property + def allSimulations(self): + if self.__allSims is None: + return None + return self.__allSims.copy() + + def sumOfAllSimulations(self): + if self.__allSims is None: + raise ValueError("No simulations done.") + s = np.sum(self.__allSims, 2) + return s + + def meanOfAllSimulations(self): + mean = np.mean(self.__allSims, 2) + return mean + + def intensityHistogram(self, sumOnly: bool = False): + if sumOnly: + data = self.sumOfAllSimulations() + else: + data = self.meanOfAllSimulations() + values, binEdges, _ = plt.hist(data.ravel(), 256) + plt.show() + return values, binEdges + + def showSimulation(self, sumOnly: bool = False): + if sumOnly: + data = self.sumOfAllSimulations() + else: + data = self.meanOfAllSimulations() + plt.imshow(data, "gray") + plt.show() + + def saveSimulation(self, path: str, sumOnly: bool = False): + if sumOnly: + data = self.sumOfAllSimulations() + else: + data = self.meanOfAllSimulations() + tfile.imwrite(path, data) + + +if __name__ == '__main__': + shape = 1000 + """ + c = SumOfFullyDeveloppedSpecklesSimulationWithSource(shape, 2) + c.runSimulationsWithCircularSources(shape // 6) + values, _ = c.intensityHistogram() + """ + k = FullyDeveloppedSpeckleSimulationWithCircularSource(shape,100) + k.runSimulation() + k.showSimulation() + k.saveSimulation(r"C:\Users\ludod\Desktop\Stage_CERVO\speckle_imagery\simsave_for_speckle_diameter\test1.tiff") + """ + k.addShotNoise(scaling=3) + """ + k.addShotNoise() + k.nonUniformIntensity(sigmax=500,sigmay=500) + k.showSimulation() + k.saveSimulation(r"C:\Users\ludod\Desktop\Stage_CERVO\speckle_imagery\simsave_for_speckle_diameter\test2.tiff") + + diff --git a/SpeckleSizeCode/PythonAutocorr/speckleCaracterization.py b/SpeckleSizeCode/PythonAutocorr/speckleCaracterization.py new file mode 100644 index 0000000..9a818e2 --- /dev/null +++ b/SpeckleSizeCode/PythonAutocorr/speckleCaracterization.py @@ -0,0 +1,131 @@ +from SpeckleSizeCode.PythonAutocorr import autocorrelation, peakMeasurement +import matplotlib.pyplot as plt +from scipy.signal import convolve2d +import numpy as np +import os + + +class SpeckleCaracerization: + + def __init__(self, imagePath: str, gaussianFilterNormalizationStdDev: float = 75, medianFilterSize: int = 3): + self.__fileName = imagePath + self.__autocorrObj = autocorrelation.Autocorrelation(imagePath) + self.__image = self.__autocorrObj.image + self.__autocorrObj.computeAutocorrelation(gaussianFilterNormalizationStdDev, medianFilterSize) + self.__autocorrelation = self.__autocorrObj.autocorrelation + self.__verticalSlice, self.__horizontalSlice = self.__autocorrObj.getSlices() + self.__histInfo = (None, None, None) + self.peakMeasureReport = {} + + @property + def fullAutocorrelation(self): + return self.__autocorrelation.copy() + + @property + def autocorrelationSlices(self): + return self.__verticalSlice.copy(), self.__horizontalSlice.copy() + + def computeFWHMOfSpecificAxisWithLinearFit(self, axis: str, maxNbPoints: int = 3, moreInUpperPart: bool = True): + cleanedAxis = axis.lower().strip() + if cleanedAxis == "horizontal": + FWHM = peakMeasurement.FullWidthAtHalfMaximumLinearFit(self.__horizontalSlice, 1, maxNbPoints, + moreInUpperPart) + FWHM_value = FWHM.findFWHM() + elif cleanedAxis == "vertical": + FWHM = peakMeasurement.FullWidthAtHalfMaximumLinearFit(self.__verticalSlice, 1, maxNbPoints, + moreInUpperPart) + FWHM_value = FWHM.findFWHM() + else: + raise ValueError(f"Axis '{axis}' not supported. Try 'horizontal' or 'vertical'.") + return FWHM_value + + def computeFWHMOfSpecificAxisWithNeighborsAveraging(self, axis: str, averageRange: float = 0.2): + cleanedAxis = axis.lower().strip() + if cleanedAxis == "horizontal": + FWHM = peakMeasurement.FullWidthAtHalfMaximumNeighborsAveraging(self.__horizontalSlice, 1, averageRange) + FWHM_value = FWHM.findFWHM() + elif cleanedAxis == "vertical": + FWHM = peakMeasurement.FullWidthAtHalfMaximumNeighborsAveraging(self.__verticalSlice, 1, averageRange) + FWHM_value = FWHM.findFWHM() + else: + raise ValueError(f"Axis '{axis}' not supported. Try 'horizontal' or 'vertical'.") + return FWHM_value + + def computeFWHMBothAxes(self, alsoReturnMean: bool = True, method: str = "mean", *args, **kwargs): + cleanedMethod = method.lower().strip() + if cleanedMethod == "linear": + vertical = self.computeFWHMOfSpecificAxisWithLinearFit("vertical", *args, **kwargs) + horizontal = self.computeFWHMOfSpecificAxisWithLinearFit("horizontal", *args, **kwargs) + elif cleanedMethod == "mean": + vertical = self.computeFWHMOfSpecificAxisWithNeighborsAveraging("vertical", *args, **kwargs) + horizontal = self.computeFWHMOfSpecificAxisWithNeighborsAveraging("horizontal", *args, **kwargs) + else: + raise ValueError(f"Method '{method}' not supported. Try 'linear' or 'error'.") + return (vertical, horizontal, (vertical + horizontal) / 2) if alsoReturnMean else (vertical, horizontal) + + def intensityHistogram(self, nbBins: int = 256, showHistogram: bool = True): + hist, bins, _ = plt.hist(self.__image.ravel(), nbBins, (0, self.__maxPossibleIntensityValue())) + plt.xlabel("Bin [-]") + plt.ylabel("Number of occurrences [-]") + plt.title(f"Intensity histogram of the speckle pattern, with {nbBins} bins.") + if showHistogram: + plt.show() + self.__histInfo = (hist, bins, nbBins) + return hist, bins + + def isFullyDevelopedSpecklePattern(self, nbBins: int = 256): + if self.__histInfo[-1] != nbBins: + self.intensityHistogram(nbBins, False) + hist, bins, _ = self.__histInfo + if np.argmax(hist) == 0: # If the maximum of the intensity distribution is at index 0, we suppose exp dist. + return True + return False + + def meanIntensity(self): + return np.mean(self.__image) + + def stdDevIntensity(self): + return np.std(self.__image) + + def medianIntensity(self): + return np.median(self.__image) + + def maxIntensity(self): + return np.max(self.__image) + + def minIntensity(self): + return np.min(self.__image) + + def contrastModulation(self): + return (self.maxIntensity() - self.minIntensity()) / (self.maxIntensity() + self.minIntensity()) + + def globalContrast(self): + return self.stdDevIntensity() / self.meanIntensity() + + def localContrast(self, kernelSize: int = 7): + if kernelSize < 2: + raise ValueError("The size of the local contrast kernel must be at least 2.") + kernel = np.ones((kernelSize, kernelSize)) + n = kernel.size + windowedAverage = convolve2d(self.__image, kernel, "valid") / n + squaredImageFilter = convolve2d(self.__image ** 2, kernel, "valid") + # Compute de sample standard deviation + stdImageWindowed = ((squaredImageFilter - n * windowedAverage ** 2) / (n - 1)) ** 0.5 + return stdImageWindowed / windowedAverage + + def __maxPossibleIntensityValue(self): + dtype = self.__image.dtype + if "float" in str(dtype): + maxPossible = 1 + elif "int" in str(dtype): + maxPossible = np.iinfo(dtype).max + else: + raise TypeError(f"The type '{dtype}' is not supported for a speckle image.") + return maxPossible + + +if __name__ == '__main__': + path = os.path.dirname(__file__) + path = os.path.join(path, "circularWithPhasesSimulations", "4pixelsCircularWithPhasesSimulations.tiff") + s = SpeckleCaracerization(path) + print(s.computeFWHMBothAxes(False)) diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/10pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/10pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..4f51415 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/10pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/12pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/12pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..afb45ef Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/12pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/14pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/14pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..d9c4f0b Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/14pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/16pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/16pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..60ce45f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/16pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/18pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/18pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..15796a6 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/18pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/20pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/20pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..9dd1745 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/20pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/22pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/22pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..c1c5833 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/22pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/24pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/24pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..a8e6fa1 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/24pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/32pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/32pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..7e87eb7 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/32pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/4pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/4pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..d751246 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/4pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/6pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/6pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..69c184c Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/6pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/8pixels_100simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/8pixels_100simulationsOfCircles.tiff new file mode 100644 index 0000000..4265333 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/100sims/8pixels_100simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/10pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/10pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..06394d9 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/10pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/12pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/12pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..894e2ed Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/12pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/14pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/14pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..c497b4c Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/14pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/16pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/16pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..976dcfa Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/16pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/18pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/18pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..797a32c Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/18pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/20pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/20pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..7f84b08 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/20pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/22pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/22pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..af4267a Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/22pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/24pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/24pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..9ee4c95 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/24pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/32pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/32pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..8d19dbf Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/32pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/4pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/4pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..2ab1f32 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/4pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/6pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/6pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..5ced159 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/6pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/8pixels_10simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/8pixels_10simulationsOfCircles.tiff new file mode 100644 index 0000000..d7a1495 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/10sims/8pixels_10simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/10pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/10pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..efdabc7 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/10pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/12pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/12pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..e43d1e0 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/12pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/14pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/14pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..9aa91b8 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/14pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/16pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/16pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..6fb7780 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/16pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/18pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/18pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..557147a Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/18pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/20pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/20pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..a751b6f Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/20pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/22pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/22pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..4fb3437 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/22pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/24pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/24pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..599addb Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/24pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/32pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/32pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..7844884 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/32pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/4pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/4pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..f560415 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/4pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/6pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/6pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..42cfa66 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/6pixels_50simulationsOfCircles.tiff differ diff --git a/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/8pixels_50simulationsOfCircles.tiff b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/8pixels_50simulationsOfCircles.tiff new file mode 100644 index 0000000..cbf6e03 Binary files /dev/null and b/SpeckleSizeCode/PythonAutocorr/sumOfCircularWithPhases/50sims/8pixels_50simulationsOfCircles.tiff differ