76 lines
2.1 KiB
Python
76 lines
2.1 KiB
Python
from scipy import ndimage
|
|
from skimage import filters,feature
|
|
import sys
|
|
import matplotlib.pyplot as plt
|
|
import math
|
|
import numpy as np
|
|
import pdb
|
|
|
|
def calculate_edges(img):
|
|
# TODO fix the performance - added ad hoc
|
|
(n,m) = img.shape
|
|
edge = np.zeros((n,m), dtype=np.bool)
|
|
# pdb.set_trace()
|
|
for i in range(0, n):
|
|
for j in range(0, m):
|
|
edge_point = False
|
|
for k in range(-1, 2):
|
|
if edge_point:
|
|
break
|
|
for l in range(-1,2):
|
|
if edge_point:
|
|
break
|
|
|
|
y = (i+k)%n
|
|
x = (j+l)%m
|
|
|
|
if img[y,x] != img[i,j]:
|
|
edge_point = True
|
|
break
|
|
edge[i,j] = edge_point
|
|
return edge
|
|
|
|
def calc_shape_corners(img_mask2, range_ext=8):
|
|
(my,mx) = ndimage.center_of_mass(img_mask2)
|
|
# edge = feature.canny(img_mask2)
|
|
edge = calculate_edges(img_mask2)
|
|
|
|
(n,m) = img_mask2.shape
|
|
|
|
print("Center of mass {}x{}".format(mx,my))
|
|
distances = np.zeros((n,m), dtype=np.float)
|
|
distances[:,:] = 0
|
|
for i in range(0, n):
|
|
for j in range(0, m):
|
|
if edge[i,j]:
|
|
dx = j - mx
|
|
dy = i - my
|
|
d = math.sqrt(dx*dx+dy*dy)
|
|
distances[i,j] = d
|
|
|
|
max_distances = ndimage.maximum_filter(distances, range_ext)
|
|
diff = np.abs(max_distances - distances)
|
|
corners = edge * (diff < 1e-3)
|
|
return corners
|
|
|
|
if __name__ == "__main__":
|
|
img = ndimage.imread(sys.argv[1])
|
|
img_gray = 0.21 * img[:,:,0] + 0.72 * img[:,:,1] + 0.07 * img[:,:,2]
|
|
otsu_lvl = filters.threshold_otsu(img_gray)
|
|
img_mask = img_gray <= otsu_lvl
|
|
img_mask2 = ndimage.median_filter(img_mask, 3)
|
|
(n,m) = img_mask2.shape
|
|
|
|
|
|
corners = calc_shape_corners(img_mask2)
|
|
|
|
mat_x = np.tile(np.arange(0,m),n).reshape((n,m))
|
|
mat_y = np.tile(np.arange(0,n),m).reshape((m,n)).T
|
|
|
|
xs = mat_x[corners]
|
|
ys = mat_y[corners]
|
|
|
|
plt.imshow(img_gray, cmap="Greys_r")
|
|
plt.plot(xs, ys, "r+")
|
|
plt.show()
|