2017-09-14 10 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

HTTPS([ 'this']に近いと思われます。 com/questions/39667089 /) – Divakar

答えて

2

ちょうどnumpyのアレイとして画像を読み込み、そして、代わりに画素をループの配列操作を使用:// stackoverflowの:

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

関連する問題