Monday, February 15, 2021

Generating a Gradient Programmatically

I've posted many times on this blog, my experiments in image generation through Python. I've been working on what I call my "Noisefield" project, where I generated a bitmap with random black and white pixels. I have now done something similar, except this time I generated a black to white gradient, using the PIL library in Python.

The idea is pretty simple. You create a vector or array of values from 0 to 255, then you repeat that 256 times, to make a square matrix, or bitmap (because Python puts in the pixels from top-left downwards and towards the right, line by line). So that way you get a gradient. I took the "LINE" variable that I created with a for loop and range() function and then multiplied it by 256 in a variable called MATRIX. I then used an iterator function on the Matrix which I called in the image-generation function by calling next(MATRIX). The result is a smooth matrix.

ADDENDUM: I have found a simpler way of generating a black to white gradient, using the np.linspace function in Numpy.

FOR YOUR INFORMATION: I have written a few blog posts in the past about generating bitmaps with random black and white pixel values, or grey values between 0 and 255. I found a much quicker way to do this using the OpenCV library (cv2). (In passing, this np.random.randint() function gives the same results as the uniform_noise function below, in the second Gist below:

Here's another way to generate noise, Gaussian noise in this case, via OpenCV (cv2). The Gaussian distribution is "smoother" in appearance, as it has mean 128 and standard deviation 20:

With mean 0 and standard deviation 256, we get a "coarser" noise distribution:

As stated, the uniform_noise "randu" function gives the same result as the previous np.random.randint() function, a uniform noise distribution:

If I add the following, "ret,thresh1 = cv2.threshold(uniform_noise,64,255,cv2.THRESH_BINARY)" and then write "cv2.imwrite("Noise.jpg",thresh1)", I get a noisy distribution with many more whites, because of the threshold value being at 64. For every pixel, the same threshold value is applied. If the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to a maximum value, in this case 255, which is pure white. This way it is possible to adjust the parseness if you will of the noisy distribution using the threshold function:

The opposite would be true if we set the treshold higher, to say 250. Then it's mostly black, or at a pixel value of 0:

No comments:

Post a Comment