File size: 3,421 Bytes
e9341b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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