Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a function <code>find_groups</code> that groups each pixel in the image into one of three categories: free, closed and border, along with a function <code>print_groups</code> to test it in a readable way.</p> <pre><code>from collections import namedtuple from copy import deepcopy def find_groups(inpixels): """ Group the pixels in the image into three categories: free, closed, and border. free: A white pixel with a path to outside the image. closed: A white pixels with no path to outside the image. border: A black pixel. Params: pixels: A collection of columns of rows of pixels. 0 is black 1 is white. Return: PixelGroups with attributes free, closed and border. Each is a list of tuples (y, x). """ # Pad the entire image with white pixels. width = len(inpixels[0]) + 2 height = len(inpixels) + 2 pixels = deepcopy(inpixels) for y in pixels: y.insert(0, 1) y.append(1) pixels.insert(0, [1 for x in range(width)]) pixels.append([1 for x in range(width)]) # The free pixels are found through a breadth first traversal. queue = [(0,0)] visited = [(0,0)] while queue: y, x = queue.pop(0) adjacent = ((y+1, x), (y-1, x), (y, x+1), (y, x-1)) for n in adjacent: if (-1 &lt; n[0] &lt; height and -1 &lt; n[1] &lt; width and not n in visited and pixels[n[0]][n[1]] == 1): queue.append(n) visited.append(n) # Remove the padding and make the categories. freecoords = [(y-1, x-1) for (y, x) in visited if (0 &lt; y &lt; height-1 and 0 &lt; x &lt; width-1)] allcoords = [(y, x) for y in range(height-2) for x in range(width-2)] complement = [i for i in allcoords if not i in freecoords] bordercoords = [(y, x) for (y, x) in complement if inpixels[y][x] == 0] closedcoords = [(y, x) for (y, x) in complement if inpixels[y][x] == 1] PixelGroups = namedtuple('PixelGroups', ['free', 'closed', 'border']) return PixelGroups(freecoords, closedcoords, bordercoords) def print_groups(ysize, xsize, pixelgroups): ys= [] for y in range(ysize): xs = [] for x in range(xsize): if (y, x) in pixelgroups.free: xs.append('.') elif (y, x) in pixelgroups.closed: xs.append('X') elif (y, x) in pixelgroups.border: xs.append('#') ys.append(xs) print('\n'.join([' '.join(k) for k in ys])) </code></pre> <p>Now to use it:</p> <pre><code>pixels = [[0, 1, 0, 0, 1, 1], [1, 0, 1, 1, 0, 1], [1, 0, 1, 1, 0, 1], [1, 0 ,1 ,1 ,0, 1], [1, 0, 1 ,0 ,1, 1], [1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1]] pixelgroups = find_groups(pixels) print_groups(7, 6, pixelgroups) print("closed: " + str(pixelgroups.closed)) </code></pre> <p>Outputs:</p> <pre><code># . # # . . . # X X # . . # X X # . . # X X # . . # X # . . . # # . . . . . . . . . closed: [(1, 2), (1, 3), (2, 2), (2, 3), (3, 2), (3, 3), (4, 2)] </code></pre> <p>You'll notice random dots and streaks are classified as borders. But you can always distinguish between real borders and streaks as follows.</p> <pre><code># pseudo code realborders = [i for i in pixelgroups.border if i has an adjacent closed pixel] streaks = [otherwise] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload