Python|用Python生成NFT超像素风格头像( 三 )


arr[1
arr[2
int(arr[3
) int(arr[4
)

class Cluster(object):
   def __init__(self pixel):
       self.center = pixel
       self.pixels = [


   def lab(self):
       return np.array([self.center.l self.center.a self.center.b
)

   '''
   防止出现在轮廓边线上 ,找临近色度最低的3x3范围
   '''
   def gradient(self lab x y height width):
       # 防止下标越界
       x y hp1 wp1 = min(x height-1) min(y width-1) min(x+1 height-1) min(y+1 width-1)
       x y hm1 wm1 = max(x 0) max(y0) max(x-1 0) max(y-1 0)
       # print (height width hp1 wp1 hm1 wm1 h w)
       gradient = np.sum((lab[hp1
[y
-lab[hm1
[y
)**2) + np.sum((lab[x
[wp1
-lab[x
[wm1
)**2)
       return gradient x y

   '''
   初始化时 , 向周边移动到最小梯度的点 , 梯度定义为lba空间下的四角色差
   '''
   def move3x3(self img_lba img_height img_width):
       cluster_gradient _ _ = self.gradient(img_lba self.center.x self.center.y img_height img_width)
       for dh in range(-1 2):
           for dw in range(-1 2):
               _x = self.center.x + dh
               _y = self.center.y + dw
               new_gradient _x _y = self.gradient(img_lba _x _y img_height img_width)
               if new_gradient < cluster_gradient:
                   self.center = Pixel(img_lba[_x
[_y
[0
img_lba[_x
[_y
[1
img_lba[_x
[_y
[2
_x _y)
                   cluster_gradient = new_gradient
   '''
   计算聚类中心 , 和当前遍历点的距离信息 , 按照图中公式
   '''
   def distance(self pixel s m):
       # calculate the delat = (lbaxy_1 - lbaxy_2) ^ 2
       dc = (self.center.l - pixel.l)**2 + (self.center.l - pixel.l)**2 + (self.center.l - pixel.l)**2
       ds = (self.center.x - pixel.x)**2 + (self.center.y - pixel.y)**2
       return math.sqrt(dc + (ds/s**2)*m**2)
   
   def cleanup_pixels(self):
       self.pixels = [

   
   def assign(self pixel):
       self.pixels.append(pixel)
           
   def update(self):
       new_center = np.array([0.0
*5)
       for p in self.pixels:
           new_center += p.tonparray()
       if len(self.pixels) > 0:
           new_center /= len(self.pixels)
       epislon = np.sum(np.square(new_center-self.center.tonparray()))
       self.center.update(new_center)
       return epislon

SLIC过程


def slic(image_path K M):
   lab height width = read_image_in_lab_space(img_path)
   clusters = intialize(lab K M height width)
   S = int(math.sqrt(height * width / K))

   espilon = 1
   max_iters = 10
   
   # 初始化 label ,distance
   l = np.full((height width) -1)
   d = np.full((height width) np.inf)