填充2D矩阵,使得两个相邻值不相同

时间:2012-12-07 03:35:19

标签: python language-agnostic numpy

我想估算算法的最坏情况,其中迭代次数取决于图像中有多少像素具有与自身不同的邻居。假设图像是灰度的,我正在寻找一种生成M x N矩阵的方法,该矩阵填充了[0, 255]范围内的随机值,其中没有两个具有相同值的像素是连续的(包括“角落”) “邻居,即这是针对8邻居的情况。”

编辑应该在原始帖子中更清晰。我希望对[0, 255]范围内的所有值进行相对统一的抽样。

怎么会这样做?解决方案的效率并不重要,我正在寻找一些容易推理的东西。

4 个答案:

答案 0 :(得分:2)

0 1 0 1 0 1 0
2 3 2 3 2 3 2
1 0 1 0 1 0 1

更一般地说,尝试为图形着色的最愚蠢的方法是依次访问每个顶点(按照您喜欢的任何顺序),并为它提供一个尚未用于与其相邻的顶点的颜色。如果(在这种情况下)你有比最大可能数量的相邻顶点更多的颜色,你就不会失去。

上面的网格是沿着每行从左到右访问矩阵并使用最小可用值的结果。您可以从可用值中随机选择一个:

import random
rows = [[None] * 10 for i in xrange(10)] # or numpy matrix
for i, row in enumerate(rows):
    for j, _ in enumerate(row):
        available = set(xrange(256))
        if j > 0:
            available.discard(row[j-1])
        if i > 0:
            available.difference_update(rows[i-1][max(0,j-1):j+2])
        row[j] = random.choice(tuple(available))
print '\n'.join(map(str, rows))

答案 1 :(得分:0)

试试这个:

import numpy as np
np.cumsum(np.cumsum(np.ones((M,N)),axis=0),axis=1) % 255

答案 2 :(得分:0)

import numpy as np
from random import sample
def foo(M,N):
    #Create an np array of size M X N
    img = np.zeros((M,N))
    #Create a colour set within grayscale
    colours = set(range(255))
    #Iterate through the entire image pixel
    for i in range(M):
        for j in range(N):
            #img[i-1:i+2,j - 1:j + 2].flatten() : neighbouring pixel
            #including the current pixel
            #colours- set(img[i-1:i+2,j - 1:j + 2].flatten() : Colours not in the neighbouring pixel
            #sample(colours- set(img[i-1:i+2,j - 1:j + 2].flatten()),1)[0]: Select one from the above
            #and assign to the current pixel
            img[i,j] = sample(colours- set(img[i-1:i+2,j - 1:j + 2].flatten()),1)[0]
    return img


>>> foo(10,10)
array([[ 153.,  128.,   15.,  163.,  180.,  189.,  186.,  228.,   65.,
         140.],
       [  52.,  229.,  220.,   54.,   79.,  105.,   11.,  146.,   29.,
          70.],
       [ 244.,  119.,  188.,  147.,  230.,  157.,   28.,  243.,  105.,
          62.],
       [ 188.,  135.,  129.,  144.,  192.,   11.,   90.,  193.,   35.,
         149.],
       [  20.,  130.,  140.,  134.,  191.,   63.,   50.,  180.,   49.,
           4.],
       [  88.,  175.,  254.,  151.,  176.,   30.,  122.,  157.,   88.,
          82.],
       [  37.,  190.,   10.,  187.,  221.,   83.,    2.,  115.,  191.,
         148.],
       [  53.,   70.,  150.,  127.,  168.,  141.,  179.,   65.,  253.,
          59.],
       [  96.,    3.,  225.,  218.,   87.,   76.,   41.,  195.,  221.,
         192.],
       [  28.,   35.,  104.,  130.,  207.,   57.,  204.,  228.,   96.,
         174.]])

答案 3 :(得分:0)

既然你提到效率并不重要,试试这个:

  from numpy import array
  import random

  available = range(256)
  M=10
  N=5
  def generate():
    return random.choice(available)

  def get_neighbours(i,j):
    neighbours = []
    try:
      neighbours.append(matrix[i][j-1])
      neighbours.append(matrix[i][j+1])
      neighbours.append(matrix[i+1][j])
      neighbours.append(matrix[i-1][j])
      neighbours.append(matrix[i-1][j-1])
      neighbours.append(matrix[i-1][j+1])
      neighbours.append(matrix[i+1][j-1])
      neighbours.append(matrix[i+1][j+1])
    except:
      pass
    return neighbours

  def remove_neighbours(neighbours):
  available = range(256)
    for i in neighbours:
       try: available.remove(i)
       except: pass
    return available

  #First initialize a random matrix without any condition
  matrix = array([[generate() for i in range(M)] for j in range(N)])

  #Apply the condition and modify the matrix
  for i in range(N):
    for j in range(M):
      neighbours = get_neighbours(i,j)
      available = remove_neighbours(neighbours)
      matrix[i][j] = generate() 

  print matrix


 [[215  91   6 110 166 214 189  63  89 107]
  [  5 136  85 200 216  87 105 223 132 112]
  [179 159 116  70   3  44 238  13  41 226]
  [ 48   0  37 248 209 162 211  61  50  40]
  [237 122 135 253 219 196  92 173 163  26]]