def segments(square_side): length = square_side // 10 out_fname = 'tmp/spots_bw.png' random.seed(int(time.time())) segments_count = 20 segments = [] fails_done = 0 fails_allowed = segments_count * 10 while len(segments) < segments_count and fails_done < fails_allowed: x = random.randint(length // 2, square_side - length // 2) # do not cross y = random.randint(length // 2, square_side - length // 2) # borders alpha = random.random() * 2 * math.pi segments.append({'x': x, 'y': y, 'alpha': alpha}) ll = [[1 for idx_y in range(square_side)] for idx_x in range(square_side)] for segment in segments: x = int(segment['x']) y = segment['y'] alpha = segment['alpha'] x1 = int(segment['x'] + length * math.cos(alpha)) for coord in range(x, x1): y1 = int(y + (coord - x) / math.cos(alpha) * math.sin(alpha)) ll[coord][y1] = 0 return ll2Image_binary(ll)
def find_borders(img, el_radius=1, bg_color=1): el = ll2Image_binary([[1 if idx_y != el_radius and idx_x != el_radius else 0 for idx_y in range(1 + 2*el_radius)] for idx_x in range(1 + 2*el_radius)]) write_svg(el, 'tmp/el.svg') bg_color = 1 erosed = erose(img, el, bg_color) d_img = difference(img, erosed) d_img.save('tmp/borders_found.png')
def disk(diameter): d = diameter # Additions of 0.5 are made for the disk # to be symmetric around the picture center return ll2Image_binary([[{ True: 0, False: 1 }[(x_idx + 0.5 - d / 2)**2 + (y_idx + 0.5 - d / 2)**2 < d**2 / 4] for y_idx in range(diameter)] for x_idx in range(diameter)])
def random_binary(square_side, **kwargs): out_fname = 'tmp/random_bw.png' save = False if 'out_fname' in kwargs.keys(): out_fname = kwargs['out_fname'] if 'save' in kwargs.keys(): save = kwargs['save'] random.seed(int(time.time())) img = ll2Image_binary( [[random.choice((0, 1)) for idx_y in range(square_side)] for idx_x in range(square_side)]) if save: if 'tmp' not in os.listdir() and 'tmp/' in out_fname: os.mkdir('tmp') img.save(out_fname) return img
def put_on(img, el, condition, bg_color=1): # Center of the structural element x_c = el.size[0] // 2 y_c = el.size[1] // 2 # Additional emptiness to add to img along x and y dx_min = x_c dx_max = el.size[0] - x_c - 1 dy_min = y_c dy_max = el.size[1] - y_c - 1 element_pixels = Image2ll_binary(el) image_pixels = expand(Image2ll_binary(img), dx_min, dx_max, dy_min, dy_max, bg_color) new_image_pixels = [[ 1 for idx_y in range(img.size[1] + dy_min + dy_max)] for idx_x in range(img.size[0] + dx_min + dx_max)] black_count = 0 for idx_x in range(dx_min, dx_min + img.size[0]): for idx_y in range(dy_min, dy_min + img.size[1]): if condition == 'any' and image_pixels[idx_x][idx_y] == 0: for dx in range(-dx_min, dx_max + 1): for dy in range(-dy_min, dy_max + 1): if element_pixels[x_c + dx][y_c + dy] == 0: if new_image_pixels[idx_x + dx][idx_y + dy] != 0: black_count += 1 new_image_pixels[idx_x + dx][idx_y + dy] = 0 elif condition == 'all': if image_pixels[idx_x][idx_y] == 0: all_match = True for dx in range(-dx_min, dx_max + 1): for dy in range(-dy_min, dy_max + 1): if (image_pixels[idx_x + dx][idx_y + dy] != 0 and element_pixels[x_c + dx][y_c + dy] == 0): all_match = False break if not all_match: break if all_match: new_image_pixels[idx_x][idx_y] = 0 black_count += 1 print('black:', black_count, 'white:', img.size[0] * img.size[1] - black_count) return ll2Image_binary(cut(new_image_pixels, dx_min, dx_max, dy_min, dy_max))
def spots_binary(square_side, **kwargs): out_fname = 'tmp/spots_bw.png' save = False if 'out_fname' in kwargs.keys(): out_fname = kwargs['out_fname'] if 'save' in kwargs.keys(): save = kwargs['save'] random.seed(int(time.time())) #img = Image.new(mode=color_mode, size=(square_side, square_side), color=1) #pixels = img.load() # Find spots' coordintates spots_count = 20 spots = [] fails_done = 0 fails_allowed = spots_count * 10 while len(spots) < spots_count and fails_done < fails_allowed: r = random.randint(1, square_side // 10) x = random.randint(r, square_side - r) # do not cross borders y = random.randint(r, square_side - r) is_close = False for spot in spots: dx = spot['x'] - x dy = spot['y'] - y if dx**2 + dy**2 < (r + spot['r'])**2: is_close = True break if is_close: fails_done += 1 else: spots.append({'x': x, 'y': y, 'r': r}) ll = [[1 for idx_y in range(square_side)] for idx_x in range(square_side)] # Draw spots for spot in spots: for dx in range(-spot['r'], spot['r'] + 1): for dy in range(-spot['r'], spot['r'] + 1): if dx**2 + dy**2 < spot['r']**2: ll[spot['x'] + dx][spot['y'] + dy] = 0 img = ll2Image_binary(ll) if save: if 'tmp' not in os.listdir() and 'tmp/' in out_fname: os.mkdir('tmp') img.save(out_fname) with open(out_fname + '_info', 'w') as f: for spot in spots: print(spot['x'], spot['y'], spot['r'], file=f) return img
def ring(diameter): d = diameter # Additions of 0.5 are made for the ring # to be symmetric around the picture center d_in = d - 2 # inner emptiness diameter result = [[{ True: 0, False: 1 }[int((x_idx + 0.5 - d / 2)**2 + (y_idx + 0.5 - d / 2)**2) < int(d**2 / 4) and int((x_idx + 0.5 - d / 2)**2 + (y_idx + 0.5 - d / 2)**2) >= int((d_in)**2 / 4)] for y_idx in range(diameter)] for x_idx in range(diameter)] # To remove too dense filling like this: # 0010 0010 # 0110 -> 0100 # 0100 0100 for x_idx in range(1, diameter - 1): for y_idx in range(1, diameter - 1): if any((not result[y_idx - 1][x_idx] + result[y_idx][x_idx - 1], not result[y_idx - 1][x_idx] + result[y_idx][x_idx + 1], not result[y_idx + 1][x_idx] + result[y_idx][x_idx - 1], not result[y_idx + 1][x_idx] + result[y_idx][x_idx + 1])): result[y_idx][x_idx] = 1 return ll2Image_binary(result)
def box(width, height, color=0): return ll2Image_binary([[color for _ in range(width)] for _ in range(height)])
if __name__ == '__main__': ll = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 0, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 0, 0, 0, 1, 1], [1, 1, 0, 1, 1, 0, 0, 0, 1, 1], [1, 0, 0, 0, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 1], ] s_erose = box(3, 1) s_dilate = box(3, 3) img_init = ll2Image_binary(ll) img_init.save('cond_init.png') img_er = erose(img_init, s_erose) img_er.save('cond_erosed.png') img_result = dilate(img_er, s_dilate) img_result.save('cond_temp.png') img = Image.new(size=img_result.size, mode='1', color=1) pixels = img.load() pixels1 = img_init.load() pixels2 = img_result.load() for idx_x in range(img.size[0]): for idx_y in range(img.size[1]): if pixels1[idx_x, idx_y] == pixels2[idx_x, idx_y] == 0: pixels[idx_x, idx_y] = 0 img.save('cond_result.png')