Skip to content
Permalink
Browse files

initial code

  • Loading branch information...
Verkhovskaya committed May 6, 2019
0 parents commit f021bd51a41c8e2dc74506966986719753756c96
@@ -0,0 +1 @@
__pycache__/
No changes.
@@ -0,0 +1,108 @@
from file_utils import save_image, load_image, image_add_location_data, get_distance_to, show_image, merge_images, simplify_image, print_image
from k_means import k_means_2
import numpy as np
import sys
from scipy.signal import convolve2d
sys.setrecursionlimit(100000)

class Cell:
def __init__(self, array, x, y):
self.array = array
self.x = x
self.y = y

cells_global = []
def split_into_two_major_colors(image_array):
colors = k_means_2(simplify_image(image_array, 10, 10))
distances = []
for i in range(len(colors)):
distances.append(get_distance_to(image_array, colors[i]))
overlays = []
for i in range(len(colors)):
is_closest = np.zeros(image_array.shape[:2]) + 1
for j in range(len(colors)):
is_closest = is_closest * (distances[i] <= distances[j])
overlays.append(is_closest)
return overlays

def split_into_individual_cells(cell_overlay, image_array, min_cell_side):
image_copy = np.copy(cell_overlay)
cells = []
for x in range(cell_overlay.shape[0]):
for y in range(cell_overlay.shape[1]):
found_locations = []
map_cell(found_locations, image_copy, x, y)
if len(found_locations) > min_cell_side**2/2:
x_start = min([location[0] for location in found_locations])
y_start = min([location[1] for location in found_locations])
new_overlay = array_overlay_from_found_locations(found_locations, image_array)
if np.sum(np.sum(new_overlay))/(new_overlay.shape[0]*new_overlay.shape[1]) > 0.5:
cells.append(Cell(new_overlay, x_start, y_start))
return cells

def array_overlay_from_found_locations(found_locations, image_array):
min_x = min([point[0] for point in found_locations])
max_x = max([point[0] for point in found_locations]) + 1
min_y = min([point[1] for point in found_locations])
max_y = max([point[1] for point in found_locations]) + 1
new_array = np.zeros(list(np.concatenate(((max_x-min_x, max_y-min_y), image_array.shape[2:]))))
for point in found_locations:
new_array[point[0]-min_x, point[1]-min_y] = image_array[point[0], point[1]]
return new_array

def map_cell(found_locations, image_array, x, y):
if x < image_array.shape[0] and y < image_array.shape[1] and x >= 0 and y >= 0:
if image_array[x,y]:
found_locations.append((x,y))
image_array[x,y] = False
map_cell(found_locations, image_array, x+1, y)
map_cell(found_locations, image_array, x, y+1)
map_cell(found_locations, image_array, x-1, y)
map_cell(found_locations, image_array, x, y-1)

def get_cell_overlay(overlays):
overlay = overlays[0]
if (np.sum(overlay[0,:]) + np.sum(overlay[:,0]) + np.sum(overlay[-1,:]) + np.sum(overlay[:,-1]))/(overlay.shape[0] + overlay.shape[1])/2 < 0.5:
return overlay
else:
return overlays[1]


def get_cells(image, min_cell_side):
overlays = split_into_two_major_colors(image)
cell_overlay = get_cell_overlay(overlays)
cells = split_into_individual_cells(cell_overlay, image, min_cell_side)

if len(cells) <= 1:
return cells
else:
all_cells = []
for cell in cells:
split_cells = get_cells(cell.array, min_cell_side)
for new_cell in split_cells:
new_cell.x += cell.x
new_cell.y += cell.y
all_cells.append(new_cell)
return all_cells

def draw_outline(image_array, cells):
new_image = np.copy(image_array)
for cell in cells:
array = cell.array
new_image[cell.x:cell.x+array.shape[0],int(cell.y+array.shape[1]/2)] = [np.max(image_array),0,0]
new_image[int(cell.x+array.shape[0]/2),cell.y:cell.y+array.shape[1]] = [np.max(image_array),0,0]
return new_image


def convert_image(in_name, out_name, min_cell_side):
image = load_image('/home/annav8/cell_counter/' + in_name)
cells = get_cells(image, min_cell_side)
save_image(draw_outline(image, cells), name=out_name)
return len(cells)

def test():
print(convert_image('cells.jpg', 'out.jpg', 10))
print(convert_image('JPEG image.jpeg', 'out2.jpg', 20))
# est()

print('hello')
@@ -0,0 +1,83 @@
import numpy as np
import matplotlib.pyplot as plt
import math

def load_image(image_path):
print('Loading image')
return plt.imread(image_path)

def print_image(image_array):
simple = simplify_image(image_array, 25, 25)
if len(image_array.shape) == 2:
for line in simple:
print(''.join([str(int(x)) for x in line]))
else:
for line in simple:
print(''.join(['1' if x[0] > 0 else '0' for x in line]))


def simplify_image(image_array, new_x, new_y):
if image_array.shape[0] <= new_x or image_array.shape[1] <= new_y:
return image_array
x_scale = 1.0*image_array.shape[0]/new_x
y_scale = 1.0*image_array.shape[1]/new_y
if len(image_array.shape) == 2:
new_image = np.zeros((new_x, new_y))
else:
new_image = np.zeros((new_x, new_y, image_array.shape[2]))
for x in range(new_x):
for y in range(new_y):
image_x = int(x*x_scale)
image_y = int(y*y_scale)
new_image[x, y] = image_array[image_x, image_y]
return new_image

def image_add_location_data(image_array, keep_location=False, cluster_factor=40):
print('Converting image to points')
new_array = []
for x in range(image_array.shape[0]):
for y in range(image_array.shape[1]):
if keep_location:
new_array.append(np.concatenate((image_array[x,y],[x/image_array.shape[0]*cluster_factor,y/image_array.shape[1]*cluster_factor])))
else:
new_array.append(image_array[x,y])
return np.array(new_array)

def get_distance_to(image_array, color_array):
print('Calculating distance to ' + str(color_array))
if len(color_array) != image_array.shape[2]:
raise Exception("Dimensions don't match")
new_array = np.zeros((image_array.shape[0], image_array.shape[1]))
for x in range(image_array.shape[0]):
for y in range(image_array.shape[1]):
new_array[x,y] = sum([(color_array[i] - image_array[x,y,i])**2 for i in range(len(color_array))])**0.5
return np.array(new_array)

def show_image(image_array):
plt.imshow(image_array)
plt.show()

def save_image(image_array, name='out.jpg'):
plt.imsave('/home/annav8/cell_counter/'+name, image_array)

def merge_images(image_arrays):
num_across = int(len(image_arrays)**0.5)
num_down = math.ceil(1.0*len(image_arrays)/num_across)
image_rows = [image_arrays[y*num_across:(y+1)*num_across] for y in range(num_down)]
row_heights = [max([image.shape[1] for image in row]) for row in image_rows]
total_width = max([sum([image.shape[0]+1 for image in row])+1 for row in image_rows])
new_image = np.zeros(np.concatenate(([total_width+1, sum(row_heights)+len(row_heights)+1], image_arrays[0].shape[2:])))+0.3
y_offset = 1
for row_id in range(len(image_rows)):
row = image_rows[row_id]
x_offset = 1
for image in row:
new_image[x_offset:x_offset+image.shape[0],y_offset:y_offset + image.shape[1]] = image
x_offset += image.shape[0] + 1
y_offset += row_heights[row_id] + 1
return new_image

def kmeans(points_array, num_colors):
print('Running kmeans, looking for ' + str(num_colors) + ' clusters')
kmeans = 0 # KMeans(n_clusters=num_colors, random_state=0).fit(points_array)
return kmeans.cluster_centers_
No changes.
BIN +134 KB in/309321078.jpg
Binary file not shown.
BIN +134 KB in/3289.jpg
Binary file not shown.
BIN +34.5 KB in/3314.jpg
Binary file not shown.
BIN +134 KB in/3342.jpg
Binary file not shown.
BIN +134 KB in/6397.jpg
Binary file not shown.
BIN +134 KB in/7817.jpg
Binary file not shown.
BIN +34.5 KB in/8312.jpg
Binary file not shown.
No changes.
BIN +24.4 KB in/978615401.jpg
Binary file not shown.
@@ -0,0 +1,51 @@
import numpy as np

def square_distance(array_1, array_2):
return sum([(array_1[i] - array_2[i])**2 for i in range(len(array_1))])

def k_means_2(image_array):
print('calculating k_means_2')
num_colors = image_array.shape[2]
color_range = np.max(image_array)
centers = [[0]*num_colors, [color_range]*num_colors]

for i in range(10):
# assign
sums = [[0]*num_colors, [0]*num_colors]
num_points = [0, 0]
for x in range(image_array.shape[0]):
for y in range(image_array.shape[1]):
point = image_array[x, y]
if sum(point) != 0:
assigned_center = 0 if square_distance(point, centers[0]) < square_distance(point, centers[1]) else 1
for k in range(num_colors):
sums[assigned_center][k] += point[k]
num_points[assigned_center] += 1

# update
new_centers = [0, 0]
for j in [0, 1]:
if num_points[j] > 0:
new_centers[j] = [sums[j][k]/num_points[j]
for k in range(num_colors)
]
else:
new_centers[j] = [color_range/2] * num_colors
# print(new_centers, i)

if sum([square_distance(new_centers[j], centers[j]) for j in [0, 1]]) < color_range/256.0:
return new_centers
else:
centers = new_centers
print('Issues converging')
return centers

def k_means_2_test():
points = np.array([[[0, 0], [1, 2], [3, 5], [5, 5]]])
k_means_2(points)

# k_means_2_test()


def none(centers):
return centers
BIN +176 KB out/309321078.jpg
Binary file not shown.
BIN +176 KB out/3289.jpg
Binary file not shown.
BIN +50.9 KB out/3314.jpg
Binary file not shown.
BIN +176 KB out/3342.jpg
Binary file not shown.
BIN +176 KB out/6397.jpg
Binary file not shown.
BIN +176 KB out/7817.jpg
Binary file not shown.
BIN +50.9 KB out/8312.jpg
Binary file not shown.
BIN +27.8 KB out/978615401.jpg
Binary file not shown.
@@ -0,0 +1,46 @@
from count_cells import convert_image
# A very simple Bottle Hello World app for you to get started with...
from bottle import default_app, route, post, request, static_file
import random

@route('/')
def hello_world():
return '''
<h1> Count the number of cells in an image </h1>
<br>
<form action="/count_cells" method="post" enctype="multipart/form-data">
Image: <input type="file" name="image" value="Choose file">
<br>
Minimum cell side length (pixels): <input type="number" name="size" value="10">
<br>
<input type="submit" value="submit">
</form>
<br>
<h2> Example: </h2>
<h3> In </h3>
<img src="/img/in/8312.jpg">
<br>
<h3> Out </h3>
<img src="/img/out/8312.jpg">
<br>
79 cells counted
<br>
'''

@post('/count_cells')
def count_cells():
side = int(request.forms.get('size'))
image = request.files.get('image')
name = str(int(random.random()*10000)) + '.jpg'
image.save('/home/annav8/cell_counter/in/' + name)
num = convert_image('in/'+name, 'out/'+name, side)
return '<img src="/img/out/' + name + '"> <br>' + str(num) + ' cells counted'

@route('/img/<dir>/<name>')
def img(dir, name):
return static_file(name, root='/home/annav8/cell_counter/'+dir)


application = default_app()

0 comments on commit f021bd5

Please sign in to comment.
You can’t perform that action at this time.