Python 如何将给定图像划分为8个唯一的饼图段?

Python 如何将给定图像划分为8个唯一的饼图段?,python,image-processing,python-imaging-library,Python,Image Processing,Python Imaging Library,我对Python非常陌生,希望执行以下操作:我想将以下图像分成8个饼图段: 我希望它看起来像这样(我在PowerPoint中制作): 背景应为黑色,图形边缘应具有独特的颜色以及每个饼图段 编辑:我写了一段代码,将整个图像分成8段: 从PIL导入图像,ImageDraw im=Image.open('C:/Users/20191881/Documents/OGO-beeldalysis/Python/asymmetrie/rotation.png')) 填充=255 draw=ImageDra

我对Python非常陌生,希望执行以下操作:我想将以下图像分成8个饼图段:

我希望它看起来像这样(我在PowerPoint中制作):

背景应为黑色,图形边缘应具有独特的颜色以及每个饼图段

编辑:我写了一段代码,将整个图像分成8段:

从PIL导入图像,ImageDraw
im=Image.open('C:/Users/20191881/Documents/OGO-beeldalysis/Python/asymmetrie/rotation.png'))
填充=255
draw=ImageDraw.draw(im)
绘制线((0,0)+im尺寸,填充)
绘制线((0,im.size[1],im.size[0],0),填充)
绘制线((0.5*im.尺寸[0],0,0.5*im.尺寸[0],im.尺寸[1]),填充)
绘制线((0,0.5*im.尺寸[1],im.尺寸[0],0.5*im.尺寸[1]),填充)
德拉鲁
im.show()
输出结果如下:


剩下要做的唯一一件事是找到一种方法,使边框内的每个黑色部分都具有唯一的颜色,并为所有白色边缘部分提供唯一的颜色。

您的代码将图像分为八个部分,这是正确的,但对于图像中心,您不会得到八个“角度相等”的部分如草图中所示的饼图线段

以下是我的解决方案,仅使用枕头和
math
模块:

导入数学
从PIL导入图像,ImageDraw
def段_颜色(i_颜色,n_颜色):
r=int((192-64)/(n_颜色-1)*i_颜色+64)
g=int((224-128)/(n_颜色-1)*i_颜色+128)
b=255
返回(r、g、b)
#加载图像;生成ImageDraw
im=Image.open('path_to/vgdrD.png')。convert('RGB'))
draw=ImageDraw.draw(im)
#饼图段数(必须是偶数)
n=8
#用定义的边缘颜色替换(全白色)边缘
边缘颜色=(255、128、0)
像素=im.load()
对于范围内的y(im.高度):
对于范围内的x(im.宽度):
如果像素[x,y]==(255,255,255):
像素[x,y]=边缘颜色
#使用定义的线颜色绘制线
线条颜色=(0,255,0)
d=最小值(im.宽度,im.高度)-10
中心=(内部宽度/2),内部高度/2)
对于范围内的i(int(n/2)):
角度=360/n*i
x1=数学cos(角度/180*数学圆周率)*d/2+中心[0]
y1=数学正弦(角度/180*数学pi)*d/2+中心[1]
x2=数学cos((180+角度)/180*数学pi)*d/2+中心[0]
y2=数学sin((180+角度)/180*数学pi)*d/2+中心[1]
绘制线([(x1,y1),(x2,y2)],线颜色)
#用定义的线段颜色填充饼图线段
对于范围(n)中的i:
角度=360/n*i+360/n/2
x=数学cos(角度/180*math.pi)*20+中心[0]
y=math.sin(角度/180*math.pi)*20+中心[1]
图像绘制。泛光填充(im,(x,y),分段颜色(i,n))
im.save(str(n)+'\u pie.png')
对于
n=8
饼图段,生成以下结果:

第一步是用所需的边缘颜色替换原始图像中的所有白色像素。当然,这里的假设是,图像中没有其他(白色)像素。此外,使用NumPy和矢量化代码可能更好,但我只想保留解决方案

下一步是画(绿色)线。这里,我使用
sin
cos
计算线的起点和终点的正确坐标

最后一步是填充饼图段的区域,参见。因此,我以与之前相同的方式计算种子点,但添加了一个角度偏移以精确命中饼图段内的点

如您所见,
n
在我的解决方案中是可变的(
n
必须为偶数):

当然,在角度分辨率方面存在一些限制,主要是由于图像较小

希望有帮助


编辑:这里有一个修改过的版本,它还允许单独着色的边

导入数学
从PIL导入图像,ImageDraw
def段_颜色(i_颜色,n_颜色):
r=int((192-64)/(n_颜色-1)*i_颜色+64)
g=int((224-128)/(n_颜色-1)*i_颜色+128)
b=255
返回(r、g、b)
def edge_颜色(i_颜色,n_颜色):
r=255
g=255-int((224-32)/(n_颜色-1)*i_颜色+32)
b=255-int((192-16)/(n_颜色-1)*i_颜色+16)
返回(r、g、b)
#加载图像;生成ImageDraw
im=Image.open('images/vgdrD.png')。convert('RGB'))
draw=ImageDraw.draw(im)
中心=(内部宽度/2),内部高度/2)
#饼图段数(必须是偶数)
n=8
#用定义的边缘颜色替换(全白色)边缘
最大长度=中间宽度+中间高度
im_pix=im.load()
对于范围(n)中的i:
掩码=图像。新建('L',im.size,0)
mask\u draw=ImageDraw.draw(mask)
角度=360/n*i
x1=数学坐标系(角度/180*数学坐标系)*最大长度+中心[0]
y1=数学正弦(角度/180*数学pi)*最大长度+中心[1]
角度=360/n*(i+1)
x2=数学cos(角度/180*数学pi)*最大长度+中心[0]
y2=数学正弦(角度/180*数学pi)*最大长度+中心[1]
遮罩画多边形([中心,(x1,y1),(x2,y2)],255)
mask_pix=mask.load()
对于范围内的y(im.高度):
对于范围内的x(im.宽度):
如果(im_pix[x,y]==(255,255,255))&(mask_pix[x,y]==255):
im_pix[x,y]=边缘颜色(i,n)
#使用定义的线颜色绘制线
线条颜色=(0,255,0)
d=最小值(im.宽度,im.高度)-10
对于范围内的i(int(n/2)):
角度=360/n*i
x1=数学cos(角度/180*数学圆周率)*d/2+中心[0]
y1=数学正弦(角度/180*数学pi)*d/2+中心[1]
x2=数学cos((180+角度)/180*数学pi)*d/2+中心[0]
y2=数学sin((180+角度)/180*数学pi)*d/2+中心[1]
绘制线([(x1,y1),(x2,y2)],线颜色)
#用定义的线段颜色填充饼图线段
对于范围(n)中的i:
角度=360/n*i+360/n/2
x=数学cos(角度/180*math.pi)*20+中心[0]
y=math.sin(角度/180*math.pi)*20+中心[1]
图像绘制。泛光填充(im,(x,y),分段颜色(i,n))
即时保存(str(n)+'