From 10cc70627b90af6a1941fbc6fff8d03dd348f044 Mon Sep 17 00:00:00 2001 From: Josef Brandt Date: Wed, 23 Sep 2020 12:48:05 +0200 Subject: [PATCH] Removal of pip noise module Replaced with numpy code from github (MIT license) --- instrumentcom/simulated/imageGenerator.py | 17 ++- instrumentcom/simulated/perlinNoise.py | 129 ++++++++++++++++++++++ requirements.txt | 1 - 3 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 instrumentcom/simulated/perlinNoise.py diff --git a/instrumentcom/simulated/imageGenerator.py b/instrumentcom/simulated/imageGenerator.py index 869c1aa..60c2a79 100644 --- a/instrumentcom/simulated/imageGenerator.py +++ b/instrumentcom/simulated/imageGenerator.py @@ -23,11 +23,11 @@ Image Generator for fake images for testing with simulated instrument interfaces import os import cv2 import numpy as np -import noise import time from copy import deepcopy import pickle from typing import Tuple, List +from .perlinNoise import generate_fractal_noise_2d from ...helperfunctions import getAppFolder @@ -46,14 +46,13 @@ def particleIsVisible(particle: np.ndarray, full: np.ndarray, pos: Tuple[int, in def addTexture(partImage: np.ndarray) -> np.ndarray: - shape = partImage.shape - startX = np.random.randint(0, 100) - startY = np.random.randint(0, 100) - for i in range(shape[0]): - for j in range(shape[1]): - noiseVal: float = noise.pnoise2((startY + i)/25, (startX + j)/25, octaves=4, persistence=0.5) - noiseVal = np.clip(noiseVal + 0.5, 0.0, 1.0) # bring to 0...1 range - partImage[i, j, :] *= (noiseVal**0.3) + noise = np.clip(generate_fractal_noise_2d((128, 128), (8, 8), 5) + 0.5, 0.0, 1.0) ** 0.3 + if partImage.shape[0] > noise.shape[0] or partImage.shape[1] > noise.shape[1]: + noise = cv2.resize(noise, partImage.shape[:2]) + + partImage[:, :, 0] *= noise[:partImage.shape[0], :partImage.shape[1]] + partImage[:, :, 1] *= noise[:partImage.shape[0], :partImage.shape[1]] + partImage[:, :, 2] *= noise[:partImage.shape[0], :partImage.shape[1]] return partImage diff --git a/instrumentcom/simulated/perlinNoise.py b/instrumentcom/simulated/perlinNoise.py new file mode 100644 index 0000000..9f6d7d4 --- /dev/null +++ b/instrumentcom/simulated/perlinNoise.py @@ -0,0 +1,129 @@ +""" +Obtained from https://github.com/pvigier/perlin-numpy + +MIT License + +Copyright (c) 2019 Pierre Vigier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + +import numpy as np + + +def interpolant(t): + return t*t*t*(t*(t*6 - 15) + 10) + + +def generate_perlin_noise_2d( + shape, res, tileable=(False, False), interpolant=interpolant +): + """Generate a 2D numpy array of perlin noise. + Args: + shape: The shape of the generated array (tuple of two ints). + This must be a multple of res. + res: The number of periods of noise to generate along each + axis (tuple of two ints). Note shape must be a multiple of + res. + tileable: If the noise should be tileable along each axis + (tuple of two bools). Defaults to (False, False). + interpolant: The interpolation function, defaults to + t*t*t*(t*(t*6 - 15) + 10). + Returns: + A numpy array of shape shape with the generated noise. + Raises: + ValueError: If shape is not a multiple of res. + """ + delta = (res[0] / shape[0], res[1] / shape[1]) + d = (shape[0] // res[0], shape[1] // res[1]) + grid = np.mgrid[0:res[0]:delta[0], 0:res[1]:delta[1]]\ + .transpose(1, 2, 0) % 1 + # Gradients + angles = 2*np.pi*np.random.rand(res[0]+1, res[1]+1) + gradients = np.dstack((np.cos(angles), np.sin(angles))) + if tileable[0]: + gradients[-1,:] = gradients[0,:] + if tileable[1]: + gradients[:,-1] = gradients[:,0] + gradients = gradients.repeat(d[0], 0).repeat(d[1], 1) + g00 = gradients[ :-d[0], :-d[1]] + g10 = gradients[d[0]: , :-d[1]] + g01 = gradients[ :-d[0],d[1]: ] + g11 = gradients[d[0]: ,d[1]: ] + # Ramps + n00 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1] )) * g00, 2) + n10 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1] )) * g10, 2) + n01 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1]-1)) * g01, 2) + n11 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1]-1)) * g11, 2) + # Interpolation + t = interpolant(grid) + n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10 + n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11 + return np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1) + + +def generate_fractal_noise_2d( + shape, res, octaves=1, persistence=0.5, + lacunarity=2, tileable=(False, False), + interpolant=interpolant +): + """Generate a 2D numpy array of fractal noise. + Args: + shape: The shape of the generated array (tuple of two ints). + This must be a multiple of lacunarity**(octaves-1)*res. + res: The number of periods of noise to generate along each + axis (tuple of two ints). Note shape must be a multiple of + (lacunarity**(octaves-1)*res). + octaves: The number of octaves in the noise. Defaults to 1. + persistence: The scaling factor between two octaves. + lacunarity: The frequency factor between two octaves. + tileable: If the noise should be tileable along each axis + (tuple of two bools). Defaults to (False, False). + interpolant: The, interpolation function, defaults to + t*t*t*(t*(t*6 - 15) + 10). + Returns: + A numpy array of fractal noise and of shape shape generated by + combining several octaves of perlin noise. + Raises: + ValueError: If shape is not a multiple of + (lacunarity**(octaves-1)*res). + """ + noise = np.zeros(shape) + frequency = 1 + amplitude = 1 + for _ in range(octaves): + noise += amplitude * generate_perlin_noise_2d( + shape, (frequency*res[0], frequency*res[1]), tileable, interpolant + ) + frequency *= lacunarity + amplitude *= persistence + return noise + + +if __name__ == '__main__': + import matplotlib.pyplot as plt + import time + t0 = time.time() + for i in range(50): + noise = generate_fractal_noise_2d((128, 128), (8, 8), 5) + print(time.time()-t0) + plt.figure() + plt.imshow(noise, cmap='gray', interpolation='lanczos') + plt.colorbar() + plt.show() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 8d0606e..6621b7d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,5 +24,4 @@ scipy==1.5.2 six==1.15.0 tifffile==2020.8.13 xlsxwriter==1.3.3 -noise==1.2.2 setuptools==49.6.0 \ No newline at end of file -- GitLab