2017-09-14 12 views
1

무작위로 픽셀을 선택하여 이미지를 분류하려고합니다. 그리고 이미지에서 원래 픽셀과 색상 공간에서 특정 유클리드 거리 인 모든 픽셀을 찾습니다. 현재 스크립트는 너무 오래 걸립니다. 이 방정식을 사용하여 이미지의 빠른 조작을 허용하는 부울 행렬을 생성 할 수 있는지 궁금합니다.이미지에서 불리언 행렬 생성하기

import PIL, glob, numpy, random, math, time 


def zone_map(picture, threshold): 
    im = PIL.Image.open(picture) 
    pix = im.load() 
    [width, height] = im.size 
    mask = numpy.zeros((width,height)) 
    while 0 in mask: 
     x = random.randint(0, width) 
     y = random.randint(0, height) 
     if mask[x, y] == 0: 
      point = pix[x,y] 
      to_average = {(x, y): pix[x, y]} 
      start = time.clock() 
      for row in range(0, width): 
       for column in range(0, height): 
        if euclid_dist(point, pix[row,column]) <= threshold: 
         to_average[(row,column)] = pix[row, column] 
      #to_average = in_sphere(pix, point) 
      end = time.clock() 
      print(end - start) 
      to_average_sum = (0, 0, 0) 
      for value in to_average.values(): 
       to_average_sum = tuple_sum(to_average_sum, value) 
      average = tuple_divide(to_average_sum, len(to_average.values())) 
      for coordinate in to_average.keys(): 
       pix[coordinate] = average 
       mask[coordinate] = 1 
       unique, counts = numpy.unique(mask, return_counts=True) 
       progress = dict(zip(unique, counts)) 
       print((progress[1]/progress[0])*100, '%') 
    im.save() 

    return im 

def euclid_dist(tuple1, tuple2): 
    """ 
    Finds euclidian distance between two points in n dimensional sapce 
    """ 
    tot_sq = 0 
    for num1, num2 in zip(tuple1, tuple2): 
     tot_sq += (num1 + num2)**2 
    return math.sqrt(tot_sq) 

def tuple_sum(tuple1, tuple2): 
    """ 
    Returns tuple comprised of sums of input tuples 
    """ 
    sums = [] 
    for num1, num2 in zip(tuple1, tuple2): 
     sums.append(num1 + num2) 
    return tuple(sums) 

def tuple_divide(tuple1, divisor): 
    """ 
    Divides numerical values of tuples by divisisor, yielding integer results 
    """ 
    quotients = [] 
    for value in tuple1: 
     quotients.append(int(round(value/divisor))) 
    return tuple(quotients) 

설명 부울 행렬, 또는이 속도를하는 방법에 대한 다른 아이디어를 통합하는 방법에 대한 정보는 크게 감상 할 수있다 : 여기

(x-cx) ^2 + (y-cy) ^2 + (z-cz)^2 < r^2 

내가 지금 사용하고있는 코드입니다.

+0

는 [ 'this' (HTTPS 부근 같다 : // 유래. co.kr/questions/39667089 /). – Divakar

답변

2

단지 NumPy와 배열로 이미지를로드하고 대신 화소 이상 반복 배열 연산을 사용

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

def zone_map(picture, threshold, show=True): 

    with PIL.Image.open(picture) as img: 
     rgb = np.array(img, dtype=np.float) 

    height, width, _ = rgb.shape 

    mask = np.zeros_like(rgb) 
    while not np.any(mask): 

     # get random pixel 
     position = np.random.randint(height), np.random.randint(width) 
     color = rgb[position] 

     # get euclidean distance of all pixels in colour space 
     distance = np.sqrt(np.sum((rgb - color)**2, axis=-1)) 

     # threshold 
     mask = distance < threshold 
     if show: # show output 
      fig, (ax1, ax2) = plt.subplots(1,2) 
      ax1.imshow(rgb.astype(np.uint8)) 
      ax2.imshow(mask, cmap='gray') 
      fig.suptitle('Random color: {}'.format(color)) 

    return mask 

def test(): 
    zone_map("Lenna.jpg", threshold=20) 
    plt.show() 

enter image description here