How to make a checkerboard in numpy?

后端 未结 24 1189
小鲜肉
小鲜肉 2020-11-30 07:52

I\'m using numpy to initialize a pixel array to a gray checkerboard (the classic representation for \"no pixels\", or transparent). It seems like there ought to be a whizzy

相关标签:
24条回答
  • 2020-11-30 08:16

    Here's a numpy solution with some checking to make sure that the width and height are evenly divisible by the square size.

    def make_checkerboard(w, h, sq, fore_color, back_color):
        """
        Creates a checkerboard pattern image
        :param w: The width of the image desired
        :param h: The height of the image desired
        :param sq: The size of the square for the checker pattern
        :param fore_color: The foreground color
        :param back_color: The background color
        :return:
        """
        w_rem = np.mod(w, sq)
        h_rem = np.mod(w, sq)
        if w_rem != 0 or h_rem != 0:
            raise ValueError('Width or height is not evenly divisible by square '
                             'size.')
        img = np.zeros((h, w, 3), dtype='uint8')
        x_divs = w // sq
        y_divs = h // sq
        fore_tile = np.ones((sq, sq, 3), dtype='uint8')
        fore_tile *= np.array([[fore_color]], dtype='uint8')
        back_tile = np.ones((sq, sq, 3), dtype='uint8')
        back_tile *= np.array([[back_color]], dtype='uint8')
        for y in np.arange(y_divs):
            if np.mod(y, 2):
                b = back_tile
                f = fore_tile
            else:
                b = fore_tile
                f = back_tile
            for x in np.arange(x_divs):
                if np.mod(x, 2) == 0:
                    img[y * sq:y * sq + sq, x * sq:x * sq + sq] = f
                else:
                    img[y * sq:y * sq + sq, x * sq:x * sq + sq] = b
        return img
    
    0 讨论(0)
  • 2020-11-30 08:18

    I modified hass's answer as follows.

    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]
    
    0 讨论(0)
  • 2020-11-30 08:20

    Here's another way to do it using ogrid which is a bit faster:

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

    Here are the timeit results:

    % 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 讨论(0)
  • 2020-11-30 08:22
    n = int(input())
    import numpy as np
    a = np.array([0])
    x = np.tile(a,(n,n))
    x[1::2, ::2] = 1
    x[::2, 1::2] = 1
    print(x)
    

    I guess this works perfectly well using numpy.tile( ) function.

    0 讨论(0)
  • 2020-11-30 08:24

    Simplest way to write checkboard matrix using tile()

    array = np.tile([0,1],n//2)
    array1 = np.tile([1,0],n//2)
    finalArray = np.array([array, array1], np.int32)
    finalArray = np.tile(finalArray,(n//2,1))
    
    0 讨论(0)
  • 2020-11-30 08:26

    Late, but for posterity:

    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 讨论(0)
提交回复
热议问题