如何在python中有效地创建重叠半透明圆圈的图像

问题描述

我正在私下研究一种遗传算法,该算法应该使用类似于 this example written in javascript彩色圆圈来近似图片

该算法包含一个函数,用于根据个人的内部表示创建图片,用于计算其 fitness,因此需要经常执行。

在下面找到一个最小的工作代码示例,该示例创建的图片与我想要的完全一样,但时间太长

import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import figureCanvasAgg
import numpy as np
from random import randint


class Circle:
    def __init__(self):
        self.position = (randint(0,200),randint(0,200))
        self.radius = randint(5,50)
        self.color = self.to_hex(randint(0,256**4))

    @staticmethod
    def to_hex(number,length=8):
        h = hex(number)[2:]
        while len(h) < length:
            h = "0" + h
        return h


def create_picture(circles,show=False):
    fig,ax = plt.subplots(figsize=(2,2))
    plt.xlim(0,200)
    plt.ylim(0,200)
    plt.subplots_adjust(top=1,bottom=0,right=1,left=0,hspace=0,wspace=0)
    plt.margins(0,0)
    for c in circles:
        new = plt.Circle(c.position,c.radius,facecolor="#" + c.color,edgecolor=None)
        ax.add_patch(new)
    ax.axis('off')
    canvas = figureCanvasAgg(fig)
    canvas.draw()
    width,height = fig.get_size_inches() * fig.get_dpi()
    img = np.frombuffer(canvas.tostring_rgb(),dtype='uint8').reshape(int(height),int(width),3)
    if show:
        plt.show()
    plt.close(fig)
    return img

create_picture([Circle() for _ in range(100)],True)

我的问题是:如何以更有效的方式在 python(不一定是 matplotlib)中创建这样的图片

我曾尝试使用 PIL,但我无法让透明度部分在那里工作。 我也尝试通过计算每个像素来计算numpy中的图片,这比我的plt解决方案还要慢。

如果有想法可以加快我的代码或替代方法,我会很高兴。

解决方法

试试 OpenCV。不幸的是,它不能开箱即用地绘制半透明圆,您必须先绘制一个圆,然后将结果与原始结果合并,这可能会减慢过程。但值得一试。

import cv2
import matplotlib.pyplot as plt
import numpy as np

def draw_circle(image,center,radius,color,alpha):
    overlay = image.copy()
    cv2.circle(image,-1)
    cv2.addWeighted(image,alpha,overlay,1 - alpha,image)

im = np.zeros((200,200,3),np.uint8) + 255
draw_circle(im,(80,80),40,(255,0),0.5)
draw_circle(im,(100,100),(0,255,(120,120),255),1/3)
plt.figure()
plt.imshow(im)
plt.show()