import deps import numpy as np import cv2 import collections import scipy import scipy.cluster import tensorflow as tf import os model_h5_path = "data/laps_models/laps.h5" try: NEURAL_MODEL = tf.keras.models.load_model(model_h5_path, compile=False) from tensorflow.keras.optimizers import RMSprop NEURAL_MODEL.compile(RMSprop(learning_rate=0.001), loss='categorical_crossentropy', metrics=['categorical_accuracy']) except Exception as e: print(f"Warning: Could not load model from {model_h5_path}: {e}") from deps.laps import model as NEURAL_MODEL def laps_intersections(lines): __lines = [[(a[0], a[1]), (b[0], b[1])] for a, b in lines] return deps.geometry.isect_segments(__lines) def laps_cluster(points, max_dist=10): Y = scipy.spatial.distance.pdist(points) Z = scipy.cluster.hierarchy.single(Y) T = scipy.cluster.hierarchy.fcluster(Z, max_dist, 'distance') clusters = collections.defaultdict(list) for i in range(len(T)): clusters[T[i]].append(points[i]) clusters = clusters.values() clusters = map(lambda arr: (np.mean(np.array(arr)[:, 0]), np.mean(np.array(arr)[:, 1])), clusters) return list(clusters) def laps_detector(img): global NC_LAYER hashid = str(hash(img.tostring())) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)[1] img = cv2.Canny(img, 0, 255) img = cv2.resize(img, (21, 21), interpolation=cv2.INTER_CUBIC) imgd = img X = [np.where(img > int(255/2), 1, 0).ravel()] X = X[0].reshape([-1, 21, 21, 1]) img = cv2.dilate(img, None) mask = cv2.copyMakeBorder(img, top=1, bottom=1, left=1, right=1, borderType=cv2.BORDER_CONSTANT, value=[255, 255, 255]) mask = cv2.bitwise_not(mask) i = 0 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) _c = np.zeros((23, 23, 3), np.uint8) for cnt in contours: (x, y), radius = cv2.minEnclosingCircle(cnt) x, y = int(x), int(y) approx = cv2.approxPolyDP(cnt, 0.1*cv2.arcLength(cnt, True), True) if len(approx) == 4 and radius < 14: cv2.drawContours(_c, [cnt], 0, (0, 255, 0), 1) i += 1 else: cv2.drawContours(_c, [cnt], 0, (0, 0, 255), 1) if i == 4: return (True, 1) pred = NEURAL_MODEL.predict(X) a, b = pred[0][0], pred[0][1] t = a > b and b < 0.03 and a > 0.975 if t: return (True, pred[0]) else: return (False, pred[0]) ################################################################################ def LAPS(img, lines, size=10): __points, points = laps_intersections(lines), [] for pt in __points: pt = list(map(int, pt)) lx1 = max(0, int(pt[0]-size-1)) lx2 = max(0, int(pt[0]+size)) ly1 = max(0, int(pt[1]-size)) ly2 = max(0, int(pt[1]+size+1)) dimg = img[ly1:ly2, lx1:lx2] dimg_shape = np.shape(dimg) if dimg_shape[0] <= 0 or dimg_shape[1] <= 0: continue re_laps = laps_detector(dimg) if not re_laps[0]: continue if pt[0] < 0 or pt[1] < 0: continue points += [pt] points = laps_cluster(points) return points