196 lines
6.4 KiB
Python
196 lines
6.4 KiB
Python
import numpy as np
|
|
from scipy.spatial import Voronoi
|
|
import cv2
|
|
|
|
|
|
class Image_Wrapper:
|
|
def __init__(self, img, x_lower, x_res, y_lower, y_res):
|
|
self.img = img
|
|
self.x_lower = x_lower
|
|
self.y_lower = y_lower
|
|
self.x_res = x_res
|
|
self.y_res = y_res
|
|
|
|
self.x_upper = self.x_lower + self.img.shape[0]*self.x_res - self.x_res
|
|
self.y_upper = self.y_lower + self.img.shape[1]*self.y_res - self.x_res
|
|
|
|
def __init__(self, img, fx, fy):
|
|
self.img = img
|
|
self.x_lower = np.min(fx)
|
|
self.y_lower = np.min(fy)
|
|
self.x_upper = np.max(fx)
|
|
self.y_upper = np.max(fy)
|
|
|
|
self.x_res = (self.x_upper - self.x_lower) / self.img.shape[0]
|
|
self.y_res = (self.y_upper - self.y_lower) / self.img.shape[0]
|
|
|
|
def val2pos(self, x, y):
|
|
x = (x - self.x_lower) / self.x_res
|
|
y = (y - self.y_lower) / self.y_res
|
|
return x, y
|
|
|
|
def check_bounds(self, xl, yl, xu, yu):
|
|
if xl > self.img.shape[0]:
|
|
print("xl lim")
|
|
return False
|
|
if yl > self.img.shape[1]:
|
|
print("yl lim")
|
|
return False
|
|
if xu < 0:
|
|
print("xu lim")
|
|
return False
|
|
if yu < 0:
|
|
print("yu lim")
|
|
return False
|
|
return True
|
|
|
|
def clean_bounds(self, xl, yl, xu, yu):
|
|
if xl < 0:
|
|
xl = 0
|
|
if yl < 0:
|
|
yl = 0
|
|
|
|
if xu > self.img.shape[0]:
|
|
xu = self.img.shape[0]
|
|
if yu > self.img.shape[1]:
|
|
yu = self.img.shape[1]
|
|
|
|
return xl, yl, xu, yu
|
|
|
|
def ext(self):
|
|
return [self.x_lower, self.x_upper, self.y_lower, self.y_upper]
|
|
|
|
|
|
class Voronoi_Evaluator:
|
|
def __init__(self, points, eval_points):
|
|
self.eval_points = eval_points
|
|
self.vor = Voronoi(points)
|
|
|
|
def __init__(self, list_points):
|
|
points = np.concatenate(list_points, axis=0)
|
|
self.eval_points = []
|
|
start = 0
|
|
for l in list_points:
|
|
stop = l.shape[0]
|
|
self.eval_points.append(np.arange(start, start + stop))
|
|
start += stop
|
|
self.vor = Voronoi(points)
|
|
|
|
def extract(self, img: Image_Wrapper):
|
|
all = []
|
|
for ev_points in self.eval_points:
|
|
temp = []
|
|
region_mask = self.vor.point_region[ev_points]
|
|
for i in np.array(self.vor.regions)[region_mask]:
|
|
if -1 in i:
|
|
print("Contains outside points")
|
|
continue
|
|
if len(i) == 0:
|
|
print("Contains outside points")
|
|
continue
|
|
pts = self.vor.vertices[i]
|
|
pts = np.stack(img.val2pos(
|
|
pts[:, 0], pts[:, 1])).astype(np.int32).T
|
|
mask = np.zeros_like(img.img)
|
|
cv2.fillConvexPoly(mask, pts, 1)
|
|
mask = mask > 0 # To convert to Boolean
|
|
temp.append(img.img[mask])
|
|
img.img[mask] = -1
|
|
all.append(temp)
|
|
return all
|
|
|
|
def extract_paint(self, img: Image_Wrapper):
|
|
counter = 1
|
|
for ev_points in self.eval_points:
|
|
region_mask = self.vor.point_region[ev_points]
|
|
print(region_mask)
|
|
for i in np.array(self.vor.regions)[region_mask]:
|
|
if -1 in i:
|
|
print("Contains outside points")
|
|
continue
|
|
if len(i) == 0:
|
|
print("Contains outside points")
|
|
continue
|
|
pts = self.vor.vertices[i]
|
|
pts = np.stack(img.val2pos(
|
|
pts[:, 0], pts[:, 1])).astype(np.int32).T
|
|
mask = np.zeros_like(img.img)
|
|
cv2.fillConvexPoly(mask, pts, 1)
|
|
mask = mask > 0 # To convert to Boolean
|
|
img.img[mask] = counter
|
|
counter += 1
|
|
return img.img
|
|
|
|
|
|
class Rect_Evaluator:
|
|
def __init__(self, points, eval_points):
|
|
self.eval_points = eval_points
|
|
self.points = points
|
|
self.length = 4
|
|
|
|
def __init__(self, list_points):
|
|
self.points = np.concatenate(list_points, axis=0)
|
|
self.eval_points = []
|
|
start = 0
|
|
for l in list_points:
|
|
stop = l.shape[0]
|
|
self.eval_points.append(np.arange(start, start + stop))
|
|
start += stop
|
|
print(self.points.shape)
|
|
print(start, " from ")
|
|
self.length = 4
|
|
|
|
def extract(self, img: Image_Wrapper):
|
|
all = []
|
|
for ev_points in self.eval_points:
|
|
temp = []
|
|
for x, y in self.points[ev_points]:
|
|
x, y = img.val2pos(x, y)
|
|
x_lower = int(x - self.length)
|
|
y_lower = int(y - self.length)
|
|
x_upper = int(x + self.length + 1)
|
|
y_upper = int(y + self.length + 1)
|
|
if img.check_bounds(x_lower, y_lower, x_upper, y_upper):
|
|
x_lower, y_lower, x_upper, y_upper = img.clean_bounds(
|
|
x_lower, y_lower, x_upper, y_upper)
|
|
temp.append(img.img[x_lower:x_upper])
|
|
all.append(temp)
|
|
return all
|
|
|
|
def extract_paint(self, img: Image_Wrapper):
|
|
val = np.nan
|
|
for ev_points in self.eval_points:
|
|
for x, y in self.points[ev_points]:
|
|
x, y = img.val2pos(x, y)
|
|
x_lower = int(x - self.length)
|
|
y_lower = int(y - self.length)
|
|
x_upper = int(x + self.length + 1)
|
|
y_upper = int(y + self.length + 1)
|
|
if img.check_bounds(x_lower, y_lower, x_upper, y_upper):
|
|
x_lower, y_lower, x_upper, y_upper = img.clean_bounds(
|
|
x_lower, y_lower, x_upper, y_upper)
|
|
|
|
img.img[y_lower:y_upper, x_lower:x_upper] = val
|
|
return img.img
|
|
|
|
#
|
|
# def main():
|
|
# np.random.seed(10)
|
|
# points = (np.random.rand(100, 2)-0.5) * 2
|
|
# voro = Voronoi_Evaluator(points, [[1],[2]])
|
|
# rect = Rect_Evaluator(points, [[1], [2]])
|
|
# Z = np.ones((1000, 1000))
|
|
# img = Image_Wrapper(Z, -5, .01, -5, .01)
|
|
# voro.extract(img)
|
|
# rect.extract(img)
|
|
#
|
|
# plt.scatter(points[[1], 0], points[[1], 1])
|
|
# plt.scatter(points[[2], 0], points[[2], 1])
|
|
# plt.imshow(img.img, extent=img.ext(), origin="lower")
|
|
# #plt.imshow(img.img, origin="lower")
|
|
# plt.show()
|
|
#
|
|
#
|
|
# if __name__ == "__main__":
|
|
# main()
|