Most image editing software has gradient map functions. Gradient maps take the brightness of a given pixel and apply a gradient of colors according to brightness. Photoshop and other software have ways to automate this, but they can’t do exactly what I want, so I thought Python might do the trick. Unfortunately I’m having a very hard time understanding or applying any of the results that come up when I search for gradient maps or color maps with Python.
All the potential solution threads I found used numpy or matplotlib which have lots of mathy lines that go right over my head… I would love some help with this. Initially I had something going with Processing, but I found the task of exporting tons of images with Processing to be weird and hacky. Plus I like Python, and want to learn how to edit and generate art with it.
This is what I’m working with right now.
from PIL import Image
myPalette = ['#1A1423', '#684756', '#AB8476']
def colorMap(pixel, palette):
# Calculate the brightness of pixel
R, G, B = pixel
brightness = sum([R, G, B])/3
# Map gradient of colors to brightness
# ???...
return mappedColor
img = Image.open('image_input.png')
pixels = img.load()
for x in range(img.size[0]):
for y in range(img.size[1]):
pixel = img.getpixel((x, y))
pixels[x, y] = colorMap(pixel, myPalette)
img.save('image_output.png')
Loading, calculating brightness, and saving are easy. I just have no idea how to apply a gradient of my palette to the pixel.
4
Answers
I know you said you didn’t want matplotlib, but I don’t think you need mathy lines to make it work. I tested it with a PNG of my own, so hopefully it works for yours as well. Here’s an example that draws heavily on this documentation.
You can do that quite easily with ImageMagick or with PIL/Numpy/OpenCV.
The first thing is to get hold of the colormap – the vertical bar down the right side of your image. I don’t have or know Clip Studio, so maybe it will let you export the colormap, or create a greyscale gradient and apply the colormap to it, then save the result as a PNG. In my case, I loaded your image into Photoshop, cut out the gradient and rotated it to make an image exactly 256-pixels wide by 1-pixel high. Enlarged, that looks like this:
colourmap.png
I also cropped your swirl thing off the left side of your image – please post images separately in future.
swirl.png
Now for applying it. First, just with ImageMagick in Terminal. I loaded your swirl image and separated it into its constituent RGB channels then averaged the channels and applied the colourmap, also known as CLUT or "Colour Lookup Table":
Next, same thing with PIL/Numpy:
You can also generate piece-wise linear colormaps like this:
That makes three segments each with a linear gradient:
then appends them together.
If you make all the segments of the colour map the same length, you will get a different interpretation:
That leads to this:
The trick is to define a mapping table that associates a color to every gray value in the range [0, 255] (in your case, you can even map [0, 255 x 3] by not taking the average).
Now to get a smooth effect, you need to change the color components regularly. The options are unlimited. Here is a typical example:
Here are two methods, one using Matplotlib and one using only OpenCV
Method #1:
OpenCV
+matplotlib.pyplot.get_cmap
We first load in the image as grayscale. By default, OpenCV reads in an image as 3-channel, 8-bit BGR. We can directly load in an image as grayscale using
cv2.imread()
with thecv2.IMREAD_GRAYSCALE
parameter or usecv2.cvtColor()
to convert a BGR image to grayscale with thecv2.COLOR_BGR2GRAY
parameter. Once we load in the image, we throw this grayscale image into Matplotlib to obtain our heatmap image. Matplotlib returns a RGB format so we must convert back to Numpy format and switch to BGR colorspace for use with OpenCV. Here’s a example using theinferno
colormap. See choosing color maps in Matplotlib for available built-in colormaps depending on your desired use case.Input image
->
Heatmap imageCode
Method #2:
cv2.applyColorMap()
We can use OpenCV’s built in heatmap function. Here’s the result using the
cv2.COLORMAP_HOT
heatmapCode
Note: Although OpenCV’s built-in implementation is short and quick, I recommend using Method #1 since there is a larger colormap selection. Matplotlib has hundreds of various colormaps and allows you to create your own custom color maps while OpenCV only has 12 to choose from. Here’s the built in OpenCV colormap selection: