2010-01-30 281 views
14

我使用numpy将像素数组初始化为灰色棋盘(“无像素”或透明的经典表示)。好像有应该是一个whizzy方式与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 

它的工作原理,但我希望为了更简单一些。

回答

2

你不能使用hstack和vstack吗?见here。 像这样:

>>> 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)) 
+0

我没有得到任何尊重这里,但这是正确的。 http://telliott99.blogspot.com/2010/01/heres-question-on-so-about-how-to-make.html – telliott99 2010-01-30 23:54:19

+0

这并没有创建一个正确大小的数组,虽然它看起来像你在您的博客文章中扩展您的答案。但是我们不能投票发表博客文章! :) Sheesh! – 2010-01-31 16:18:04

10

这应该做到这一点

你想(只是传递的宽度和高度,为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]]) 

与此2D阵列,它是简单的渲染的图像棋盘,像这样:

>>> import matplotlib.pyplot as PLT 

>>> fig, ax = PLT.subplots() 
>>> ax.imshow(checkerboard, cmap=PLT.cm.gray, interpolation='nearest') 
>>> PLT.show() 
+0

这很接近,虽然你必须小心一些事情:我希望检查跨越1个像素(我把它们作为15),并且你不能认为检查将平均适合宽度和希望棋盘的高度。 – 2010-01-30 21:50:06

+0

不错! ro可以简写为re^1。(只是XORing与1) – 2011-11-10 03:12:53

+0

这适用于偶数和非偶数宽度/高度: 'import numpy' 'def棋盘(w,h,a = 0,b = 1):' 'row0 = numpy。 r_ [int(w/2.0)* [a,b] +(w%2)* [a]]' 'row1 = row0^1' 'return numpy.row_stack(int(h/2.0)*(row0 ,row1)+(h%2)*(row0,))' – 2015-02-13 17:17:45

3

我不知道这是否是比我有更好的:

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) 
6

这里的另一种方式做它用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)) 

下面是使用timeit结果:

% 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 
+0

如果我的像素颜色不是纯灰色的,你能否适应这种情况?假设我想要两种颜色(0xFF,0x80,0x00)和(0x80,0xFF,0x00) – 2010-01-31 16:16:57

+0

当然。这是一个糟糕的设计选择,我认为颜色必须是灰色的...... – unutbu 2010-01-31 17:22:25

2

较晚,但为后人:

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] 
0

最近我想相同的功能,我修改了道格的回答有点如下:

def gen_checkerboard(grid_num, grid_size): 
    row_even = grid_num/2 * [0,1] 
    row_odd = grid_num/2 * [1,0] 
    checkerboard = numpy.row_stack(grid_num/2*(row_even, row_odd)) 
    return checkerboard.repeat(grid_size, axis = 0).repeat(grid_size, axis = 1) 
0

我修改过哈斯的答案如下。

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] 
+3

理想情况下,您会指出这个答案比另一个更有优势,而不仅仅告诉我们您修改了它。 – 2013-11-21 15:44:49

5

我使用Kronecker productkron

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

在本例中的棋盘具有2 * 4 = 8在每个方向上10×10的尺寸的字段。

+0

优雅与代数的答案!可能的改进(与大多数其他答案一样)将使用OP的原始灰度来说明一般性。 – Tanaya 2016-09-07 02:34:19

0
import numpy as np 
x = np.ones((3,3)) 
print("Checkerboard pattern:") 
x = np.zeros((8,8),dtype=int) 
x[1::2,::2] = 1 
x[::2,1::2] = 1 
print(x) 
0
a=np.array(([1,0]*4+[0,1]*4)*4).reshape((8,8)) 


[[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]]