Как сделать шахматную доску в NumPy? - PullRequest
19 голосов
/ 31 января 2010

Я использую numpy для инициализации массива пикселей на серой шахматной доске (классическое представление для «без пикселей» или прозрачный). Кажется, должен быть изумительный способ сделать это с помощью удивительных операций присваивания / нарезки / нарезки массива numpy, но это лучшее, что я придумал:

w, h = 600, 800
sq = 15    # width of each checker-square
self.pix = numpy.zeros((w, h, 3), dtype=numpy.uint8)
# Make a checkerboard
row = [[(0x99,0x99,0x99),(0xAA,0xAA,0xAA)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 0]] = row
row = [[(0xAA,0xAA,0xAA),(0x99,0x99,0x99)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 1]] = row

Это работает, но я надеялся на что-то более простое.

Ответы [ 18 ]

13 голосов
/ 31 января 2010

это должно сделать

шахматная доска любого размера, которую вы хотите (просто укажите ширину и высоту, как w, h); также я жестко запрограммировал высоту / ширину ячейки в 1, хотя, конечно, это также может быть параметризовано так, чтобы произвольное значение передавалось в:

>>> import numpy as NP

>>> def build_checkerboard(w, h) :
      re = NP.r_[ w*[0,1] ]              # even-numbered rows
      ro = NP.r_[ w*[1,0] ]              # odd-numbered rows
      return NP.row_stack(h*(re, ro))


>>> checkerboard = build_checkerboard(5, 5)

>>> checkerboard
 Out[3]: array([[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]])

с этим двумерным массивом просто визуализировать изображение шахматной доски, например:

>>> import matplotlib.pyplot as PLT

>>> fig, ax = PLT.subplots()
>>> ax.imshow(checkerboard, cmap=PLT.cm.gray, interpolation='nearest')
>>> PLT.show()
10 голосов
/ 25 мая 2016

Я бы использовал продукт Kronecker kron:

np.kron([[1, 0] * 4, [0, 1] * 4] * 4, np.ones((10, 10)))

Шахматная доска в этом примере имеет 2 * 4 = 8 полей размером 10x10 в каждом направлении.

6 голосов
/ 31 января 2010

Вот еще один способ сделать это, используя ogrid, что немного быстрее:

import numpy as np
import Image

w, h = 600, 800
sq = 15
color1 = (0xFF, 0x80, 0x00)
color2 = (0x80, 0xFF, 0x00)

def use_ogrid():
    coords = np.ogrid[0:w, 0:h]
    idx = (coords[0] // sq + coords[1] // sq) % 2
    vals = np.array([color1, color2], dtype=np.uint8)
    img = vals[idx]
    return img

def use_fromfunction():
    img = np.zeros((w, h, 3), dtype=np.uint8)
    c = np.fromfunction(lambda x, y: ((x // sq) + (y // sq)) % 2, (w, h))
    img[c == 0] = color1
    img[c == 1] = color2
    return img

if __name__ == '__main__':
    for f in (use_ogrid, use_fromfunction):
        img = f()
        pilImage = Image.fromarray(img, 'RGB')
        pilImage.save('{0}.png'.format(f.func_name))

Вот результаты:

% python -mtimeit -s"import test" "test.use_fromfunction()"
10 loops, best of 3: 307 msec per loop
% python -mtimeit -s"import test" "test.use_ogrid()"
10 loops, best of 3: 129 msec per loop
4 голосов
/ 30 мая 2011

Поздно, но для потомков:

def check(w, h, c0, c1, blocksize):
  tile = np.array([[c0,c1],[c1,c0]]).repeat(blocksize, axis=0).repeat(blocksize, axis=1)
  grid = np.tile(tile, ( h/(2*blocksize)+1, w/(2*blocksize)+1, 1))
  return grid[:h,:w]
4 голосов
/ 31 января 2010

Я не уверен, что это лучше, чем у меня было:

c = numpy.fromfunction(lambda x,y: ((x//sq) + (y//sq)) % 2, (w,h))
self.chex = numpy.array((w,h,3))
self.chex[c == 0] = (0xAA, 0xAA, 0xAA)
self.chex[c == 1] = (0x99, 0x99, 0x99)
3 голосов
/ 31 января 2010

Разве вы не можете использовать hstack и vstack? Смотрите здесь . Как это:

>>> import numpy as np
>>> b = np.array([0]*4)
>>> b.shape = (2,2)
>>> w = b + 0xAA
>>> r1 = np.hstack((b,w,b,w,b,w,b))
>>> r2 = np.hstack((w,b,w,b,w,b,w))
>>> board = np.vstack((r1,r2,r1,r2,r1,r2,r1))
2 голосов
/ 23 февраля 2018
import numpy as np

a=np.array(([1,0]*4+[0,1]*4)*4).reshape((8,8))
print(a)


[[1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]]
2 голосов
/ 06 августа 2018
def checkerboard(shape):
    return np.indices(shape).sum(axis=0) % 2

Самое компактное, возможно, самое быстрое и единственное опубликованное решение, которое обобщается на n-измерения.

2 голосов
/ 17 января 2018
import numpy as np
x = np.ones((3,3))
print("Checkerboard pattern:")
x = np.zeros((8,8),dtype=int)
# (odd_rows, even_columns)
x[1::2,::2] = 1
# (even_rows, odd_columns)
x[::2,1::2] = 1
print(x)
1 голос
/ 21 ноября 2013

Я изменил ответ Хасса следующим образом.

import math
import numpy as np

def checkerboard(w, h, c0, c1, blocksize):
        tile = np.array([[c0,c1],[c1,c0]]).repeat(blocksize, axis=0).repeat(blocksize, axis=1)
        grid = np.tile(tile,(int(math.ceil((h+0.0)/(2*blocksize))),int(math.ceil((w+0.0)/(2*blocksize)))))
        return grid[:h,:w]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...