绘制色调、饱和度渐变排列的图像(利用Python实现)
思路:
绘制色调、饱和度渐变排列的图像 —> 随着图像像素坐标的变换,色调的值、饱和度的值按一定规律变化即可 —> 利用循环,随着像素坐标变化,赋予不同
的色调,饱和度的值
PIL的ImageDraw模块中的point函数可以对图像单个像素赋予hsl形式的值,使用的格式为:
ImageDraw.point(xy, fill=None)
其中xy是表示坐标的元组,fill是填充的颜色
我们需要利用色调和饱和度的信息,PIL库中定义HSL类型颜色的用法为:color = hsl(hue, saturation%, lightness%)
需要注意的是颜色的定义由字符串给出,所以实际使用中的形式为:
fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,luminance)
其中,色调是给定的颜色为0到360之间的角度(红色=0,绿色=120,蓝色=240),饱和度为0%到100%之间的值(灰色=0%,全色=100%),明度为0%到100%之间的值
首先导入相应的package
我使用使用anaconda创建了名为DIP的虚拟环境,然后安装了pillow、matplotlib等常用的库
PIL库用来绘制图像,matplot库用来显示生成的结果,math库引入一些数学计算方法
from PIL import Image, ImageDraw
from matplotlib import pyplot as plt
import numpy as np
import math
绘制矩形颜色渐变图
def rectangle_colormap(width,length,intensity):
"""
绘制矩形颜色渐变图函数
input:
:width:生成图片的宽
:length:生成图片的长
:intensity:colormap的强度
ouput:
:image:颜色渐变图
"""
matrix = 255*np.ones((width,length,3),dtype='uint8')
image = Image.fromarray(matrix)
# 生成一个Draw类的名为draw的对象
draw = ImageDraw.Draw(image)
# 利用循环,改变像素的色调和饱和度的信息,达到渐变的效果
for y in range (0,width):
for x in range (0,length):
hue = x/length*360
saturation = y/width*100
draw.point([x, y], fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,intensity))
return image
# 设置图像的长和宽
plt.figure(figsize=(12, 12))
width,length = 40, 50
image1 = rectangle_colormap(width,length,40)
plt.subplot(221)
plt.imshow(image1)
plt.title('width=40,length = 50, intensity = 40')
image2 = rectangle_colormap(width,length,70)
plt.subplot(222)
plt.imshow(image2)
plt.title('width=40,length = 50, intensity = 70')
width,length = 60, 80
image3 = rectangle_colormap(width,length,30)
plt.subplot(223)
plt.imshow(image3)
plt.title('width=60,length = 80, intensity = 30')
image4 = rectangle_colormap(width,length,50)
plt.subplot(224)
plt.imshow(image4)
plt.title('width=60,length = 80, intensity = 50')
plt.show()
绘制圆盘状颜色变换图
整体思路与绘制矩形颜色渐变图一致,先生成一个[-1,1]
之间的数组,间距为0.01(保证采样的精度,防止出现像素感),然后先生成直角坐标,最后转化为极坐标,色度随着角度发生变换,饱和度随着半径增加而增加
def cart2pol(x, y):
"""
实现直角坐标和极坐标之间的坐标转换
"""
rho = np.sqrt(x**2 + y**2)
phi = np.arctan2(y, x)
return(rho, phi)
def circular_colormap(radis,intensity):
"""
input:
:radis: 圆形颜色渐变图的半径大小
:intensity: 圆形渐变图的整体强度大小
return:
:image: 圆形渐变图
"""
x = np.arange(-radis, radis, radis/100)
y = np.arange(-radis, radis, radis/100)
xx, yy = np.meshgrid(x, y)
rhp, phi = cart2pol(xx, yy)
matrix2 = 255*np.zeros((xx.shape[0],xx.shape[1],3),dtype='uint8')
image = Image.fromarray(matrix2)
draw = ImageDraw.Draw(image)
phi += math.pi
for x in range (0,xx.shape[0]):
for y in range (0,xx.shape[1]):
if rhp[x,y]<1:
saturation = rhp[x,y]/1*100
hue = phi[x,y]/(2*math.pi)*360
draw.point([x, y], fill='hsl(%d,%d%%,%d%%)'%(hue,saturation,intensity))
return image
# 设置图像的长和宽
plt.figure(figsize=(12, 12))
width,length = 40, 50
image1 = circular_colormap(1,40)
plt.subplot(221)
plt.imshow(image1)
plt.title('radis = 1,intensity = 40')
image2 = circular_colormap(1,60)
plt.subplot(222)
plt.imshow(image2)
plt.title('radis = 1,intensity = 60')
width,length = 60, 80
image3 = circular_colormap(1.5,40)
plt.subplot(223)
plt.imshow(image3)
plt.title('radis = 1.5,intensity = 40')
image4 = circular_colormap(1.5,60)
plt.subplot(224)
plt.imshow(image4)
plt.title('radis = 1.5,intensity = 60')
plt.show()
参考资料
PIL图像处理库关于HSL颜色赋值
https://pillow.readthedocs.io/en/stable/reference/ImageColor.html?highlight=hsl stackoverflow关于HSL颜色赋值的使用
https://stackoverflow.com/questions/17049777/hsl-python-syntax-pil