问题描述
我正在私下研究一种遗传算法,该算法应该使用类似于 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()