예제 #1
0
파일: slid.py 프로젝트: vietanhdev/chessbot
def slid_clahe(img, limit=2, grid=(3, 3), iters=5):
    """repair using CLAHE algorithm (adaptive histogram equalization)"""
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    for i in range(iters):
        img = cv2.createCLAHE(clipLimit=limit, \
          tileGridSize=grid).apply(img)
    debug.image(img).save("slid_clahe_@1")
    if limit != 0:
        kernel = np.ones((10, 10), np.uint8)
        img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
        debug.image(img).save("slid_clahe_@2")
    return img
예제 #2
0
파일: slid.py 프로젝트: vietanhdev/chessbot
def pSLID(img, thresh=150):
    """find all lines using different settings"""
    print(utils.call("pSLID(img)"))
    segments = []
    i = 0
    for key, arr in enumerate(NC_SLID_CLAHE):
        tmp = slid_clahe(img, limit=arr[0], grid=arr[1], iters=arr[2])
        __segments = list(slid_detector(slid_canny(tmp), thresh))
        segments += __segments
        i += 1
        print("FILTER: {} {} : {}".format(i, arr, len(__segments)))
        debug.image(slid_canny(tmp)).lines(__segments).save("pslid_F%d" % i)
    return segments
예제 #3
0
def llr_pad(four_points, img):
    print(utils.call("llr_pad(four_points)"))
    pco = pyclipper.PyclipperOffset()
    pco.AddPath(four_points, pyclipper.JT_MITER, pyclipper.ET_CLOSEDPOLYGON)

    padded = pco.Execute(60)[0]
    debug.image(img) \
     .points(four_points, color=(0,0,255)) \
     .points(padded, color=(0,255,0)) \
     .lines([[four_points[0], four_points[1]], [four_points[1], four_points[2]], \
             [four_points[2], four_points[3]], [four_points[3], four_points[0]]], \
       color=(255,255,255)) \
     .lines([[padded[0], padded[1]], [padded[1], padded[2]], \
             [padded[2], padded[3]], [padded[3], padded[0]]], \
       color=(255,255,255)) \
    .save("llr_final_pad")

    return pco.Execute(60)[
        0]  # 60,70/75 is best (with buffer/for debug purpose)
예제 #4
0
def LAPS(img, lines, size=10):
    print(utils.call("LAPS(img, lines)"))

    __points, points = laps_intersections(lines), []
    debug.image(img).points(__points, size=3).save("laps_in_queue")

    for pt in __points:
        # pixels are in integers
        pt = list(map(int, pt))

        # size of our analysis area
        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))

        # cropping for detector
        dimg = img[ly1:ly2, lx1:lx2]
        dimg_shape = np.shape(dimg)

        # not valid
        if dimg_shape[0] <= 0 or dimg_shape[1] <= 0: continue

        # use neural network
        re_laps = laps_detector(dimg)
        if not re_laps[0]: continue

        # add if okay
        if pt[0] < 0 or pt[1] < 0: continue
        points += [pt]
    points = laps_cluster(points)

    debug.image(img).points(points, size=5, \
     color=debug.color()).save("laps_good_points")

    return points
예제 #5
0
파일: slid.py 프로젝트: vietanhdev/chessbot
def SLID(img, segments):
    # FIXME: zrobic 2 rodzaje haszowania (katy + pasy [blad - delta])
    print(utils.call("SLID(img, segments)"))

    global all_points
    all_points = []
    pregroup, group, hashmap, raw_lines = [[], []], {}, {}, []

    __cache = {}

    def __dis(a, b):
        idx = hash("__dis" + str(a) + str(b))
        if idx in __cache: return __cache[idx]
        __cache[idx] = np.linalg.norm(na(a) - na(b))
        return __cache[idx]

    X = {}

    def __fi(x):
        if x not in X: X[x] = 0
        if (X[x] == x or X[x] == 0): X[x] = x
        else: X[x] = __fi(X[x])
        return X[x]

    def __un(a, b):
        ia, ib = __fi(a), __fi(b)
        X[ia] = ib
        group[ib] |= group[ia]
        #group[ia] = set()
        #group[ia] = set()

    # shortest path // height
    nln = lambda l1, x, dx: \
     np.linalg.norm(np.cross(na(l1[1])-na(l1[0]),
           na(l1[0])-na(   x)))/dx

    def __similar(l1, l2):
        da, db = __dis(l1[0], l1[1]), __dis(l2[0], l2[1])
        # if da > db: l1, l2, da, db = l2, l1, db, da

        d1a, d2a = nln(l1, l2[0], da), nln(l1, l2[1], da)
        d1b, d2b = nln(l2, l1[0], db), nln(l2, l1[1], db)

        ds = 0.25 * (d1a + d1b + d2a + d2b) + 0.00001
        #print(da, db, abs(da-db))
        #print(int(da/ds), int(db/ds), "|", int(abs(da-db)), int(da+db),
        #		int(da+db)/(int(abs(da-db))+0.00001))
        alfa = 0.0625 * (da + db)  #15
        # FIXME: roznica???
        #if d1 + d2 == 0: d1 += 0.00001 # [FIXME]: divide by 0
        t1 = (da / ds > alfa and db / ds > alfa)
        if not t1: return False  # [FIXME]: dist???
        return True

    def __generate(a, b, n):
        points = []
        t = 1 / n
        for i in range(n):
            x = a[0] + (b[0] - a[0]) * (i * t)
            y = a[1] + (b[1] - a[1]) * (i * t)
            points += [[int(x), int(y)]]
        return points

    def __analyze(group):
        global all_points
        points = []
        for idx in group:
            points += __generate(*hashmap[idx], 10)
        _, radius = cv2.minEnclosingCircle(na(points))
        w = radius * (math.pi / 2)
        vx, vy, cx, cy = cv2.fitLine(na(points), cv2.DIST_L2, 0, 0.01, 0.01)
        # debug.color()
        all_points += points
        return [[int(cx - vx * w), int(cy - vy * w)],
                [int(cx + vx * w), int(cy + vy * w)]]

    for l in segments:
        h = hash(str(l))
        t1 = l[0][0] - l[1][0]
        t2 = l[0][1] - l[1][1]
        hashmap[h] = l
        group[h] = set([h])
        X[h] = h
        if abs(t1) < abs(t2): pregroup[0].append(l)
        else: pregroup[1].append(l)

    debug.image(img.shape) \
     .lines(pregroup[0], color=debug.color()) \
     .lines(pregroup[1], color=debug.color()) \
    .save("slid_pre_groups")

    for lines in pregroup:
        for i in range(len(lines)):
            l1 = lines[i]
            h1 = hash(str(l1))
            #print(h1, __fi(h1))
            if (X[h1] != h1): continue
            #if (__fi(h1) != h1): continue
            for j in range(i + 1, len(lines)):
                l2 = lines[j]
                h2 = hash(str(l2))
                #if (__fi(h2) != h2): continue
                if (X[h2] != h2): continue
                #if (len(group[h2])==0): continue
                if not __similar(l1, l2): continue
                __un(h1, h2)  # union & find
                # break # FIXME

    __d = debug.image(img.shape)
    for i in group:
        #if (__fi(i) != i): continue
        if (X[i] != i): continue
        #if len(group[i]) == 0: continue
        ls = [hashmap[h] for h in group[i]]
        __d.lines(ls, color=debug.color())
    __d.save("slid_all_groups")

    for i in group:
        #if (__fi(i) != i): continue
        if (X[i] != i): continue
        #if len(group[i]) == 0: continue
        #if (__fi(i) != i): continue
        raw_lines += [__analyze(group[i])]
    debug.image(img.shape).lines(raw_lines).save("slid_final")

    debug.image(img.shape)\
     .points(all_points, color=(0,255,0), size=2)\
    .lines(raw_lines).save("slid_final2")

    return raw_lines
예제 #6
0
def LLR(img, points, lines):
    print(utils.call("LLR(img, points, lines)"))
    old = points

    # --- otoczka
    def __convex_approx(points, alfa=0.01):
        hull = scipy.spatial.ConvexHull(na(points)).vertices
        cnt = na([points[pt] for pt in hull])
        approx = cv2.approxPolyDP(cnt,alfa*\
           cv2.arcLength(cnt,True),True)
        return llr_normalize(itertools.chain(*approx))

    # ---

    # --- geometria
    __cache = {}

    def __dis(a, b):
        idx = hash("__dis" + str(a) + str(b))
        if idx in __cache: return __cache[idx]
        __cache[idx] = np.linalg.norm(na(a) - na(b))
        return __cache[idx]

    nln = lambda l1, x, dx: \
     np.linalg.norm(np.cross(na(l1[1])-na(l1[0]),
           na(l1[0])-na(   x)))/dx
    # ---

    pregroup = [[], []]  # podzial na 2 grupy (dla ramki)
    S = {}  # ranking ramek // wraz z wynikiem

    points = llr_correctness(llr_normalize(points), img.shape)  # popraw punkty

    # --- clustrowanie
    import sklearn.cluster
    __points = {}
    points = llr_polysort(points)
    __max, __points_max = 0, []
    alfa = math.sqrt(cv2.contourArea(na(points)) / 49)
    X = sklearn.cluster.DBSCAN(eps=alfa * 4).fit(points)  # **(1.3)
    for i in range(len(points)):
        __points[i] = []
    for i in range(len(points)):
        if X.labels_[i] != -1: __points[X.labels_[i]] += [points[i]]
    for i in range(len(points)):
        if len(__points[i]) > __max:
            __max = len(__points[i])
            __points_max = __points[i]
    if len(__points) > 0 and len(points) > 49 / 2: points = __points_max
    print(X.labels_)
    # ---

    # tworzymy zewnetrzny pierscien
    ring = __convex_approx(llr_polysort(points))

    n = len(points)
    beta = n * (5 / 100)  # beta=n*(100-(skutecznosc LAPS))
    alfa = math.sqrt(cv2.contourArea(na(points)) /
                     49)  # srednia otoczka siatki

    x = [p[0] for p in points]  # szukamy punktu
    y = [p[1] for p in points]  # centralnego skupiska
    centroid = (sum(x) / len(points), \
          sum(y) / len(points))

    print(alfa, beta, centroid)

    #        C (x2, y2)        d=(x_1−x_0)^2+(y_1−y_0)^2, t=d_t/d
    #      B (x1, y1)          (x_2,y_2)=(((1−t)x_0+tx_1),((1−t)y_0+ty_1))
    #    .                    t=(x_0-x_2)/(x_0-x_1)
    #  .
    # A (x0, y0)

    def __v(l):
        y_0, x_0 = l[0][0], l[0][1]
        y_1, x_1 = l[1][0], l[1][1]

        x_2 = 0
        t = (x_0 - x_2) / (x_0 - x_1 + 0.0001)
        a = [int((1 - t) * x_0 + t * x_1), int((1 - t) * y_0 + t * y_1)][::-1]

        x_2 = img.shape[0]
        t = (x_0 - x_2) / (x_0 - x_1 + 0.0001)
        b = [int((1 - t) * x_0 + t * x_1), int((1 - t) * y_0 + t * y_1)][::-1]

        poly1 = llr_polysort([[0, 0], [0, img.shape[0]], a, b])
        s1 = llr_polyscore(na(poly1),
                           points,
                           centroid,
                           beta=beta,
                           alfa=alfa / 2)
        poly2 = llr_polysort([a, b, \
          [img.shape[1],0], [img.shape[1],img.shape[0]]])
        s2 = llr_polyscore(na(poly2),
                           points,
                           centroid,
                           beta=beta,
                           alfa=alfa / 2)

        return [a, b], s1, s2

    def __h(l):
        x_0, y_0 = l[0][0], l[0][1]
        x_1, y_1 = l[1][0], l[1][1]

        x_2 = 0
        t = (x_0 - x_2) / (x_0 - x_1 + 0.0001)
        a = [int((1 - t) * x_0 + t * x_1), int((1 - t) * y_0 + t * y_1)]

        x_2 = img.shape[1]
        t = (x_0 - x_2) / (x_0 - x_1 + 0.0001)
        b = [int((1 - t) * x_0 + t * x_1), int((1 - t) * y_0 + t * y_1)]

        poly1 = llr_polysort([[0, 0], [img.shape[1], 0], a, b])
        s1 = llr_polyscore(na(poly1),
                           points,
                           centroid,
                           beta=beta,
                           alfa=alfa / 2)
        poly2 = llr_polysort([a, b, \
          [0, img.shape[0]], [img.shape[1], img.shape[0]]])
        s2 = llr_polyscore(na(poly2),
                           points,
                           centroid,
                           beta=beta,
                           alfa=alfa / 2)

        return [a, b], s1, s2

    for l in lines:  # bedziemy wszystkie przegladac
        for p in points:  # odrzucamy linie ktore nie pasuja
            # (1) linia przechodzi blisko dobrego punktu
            t1 = nln(l, p, __dis(*l)) < alfa
            # (2) linia przechodzi przez srodek skupiska
            t2 = nln(l, centroid, __dis(*l)) > alfa * 2.5  # 3
            # (3) linia nalezy do pierscienia
            # t3 = True if p in ring else False
            if t1 and t2:
                #if (t1 and t2) or (t1 and t3 and t2): # [1 and 2] or [1 and 3 and 2]
                tx, ty = l[0][0] - l[1][0], l[0][1] - l[1][1]
                if abs(tx) < abs(ty):
                    ll, s1, s2 = __v(l)
                    o = 0
                else:
                    ll, s1, s2 = __h(l)
                    o = 1
                if s1 == 0 and s2 == 0: continue
                pregroup[o] += [ll]

    pregroup[0] = llr_unique(pregroup[0])
    pregroup[1] = llr_unique(pregroup[1])

    debug.image(img) \
     .lines(lines, color=(0,0,255)) \
     .points(laps_intersections(lines), color=(255,0,0), size=2) \
    .save("llr_debug_1")

    debug.image(img) \
     .points(laps_intersections(lines), color=(0,0,255), size=2) \
     .points(old, color=(0,255,0)) \
    .save("llr_debug_2")

    debug.image(img) \
     .lines(lines, color=(0,0,255)) \
     .points(points, color=(0,0,255)) \
     .points(ring, color=(0,255,0)) \
     .points([centroid], color=(255,0,0)) \
    .save("llr_debug")

    debug.image(img) \
     .lines(pregroup[0], color=(0,0,255)) \
     .lines(pregroup[1], color=(255,0,0)) \
    .save("llr_pregroups")

    print("---------------------")
    for v in itertools.combinations(pregroup[0], 2):  # poziome
        for h in itertools.combinations(pregroup[1], 2):  # pionowe
            poly = laps_intersections([v[0], v[1], h[0], h[1]])  # przeciecia
            poly = llr_correctness(poly, img.shape)  # w obrazku
            if len(poly) != 4: continue  # jesl. nie ma
            poly = na(llr_polysort(llr_normalize(poly)))  # sortuj
            if not cv2.isContourConvex(poly): continue  # wypukly?
            S[-llr_polyscore(poly, points, centroid, \
             beta=beta, alfa=alfa/2)] = poly                 # dodaj

    S = collections.OrderedDict(sorted(S.items()))  # max
    K = next(iter(S))
    print("key --", K)
    four_points = llr_normalize(S[K])  # score

    # XXX: pomijanie warst, lub ich wybor? (jesli mamy juz okay)
    # XXX: wycinanie pod sam koniec? (modul wylicznia ile warstw potrzebnych)

    print("POINTS:", len(points))
    print("LINES:", len(lines))

    debug.image(img).points(four_points).save("llr_four_points")

    debug.image(img) \
     .points(points, color=(0,255,0)) \
      .points(four_points, color=(0,0,255)) \
     .points([centroid], color=(255,0,0)) \
     .lines([[four_points[0], four_points[1]], [four_points[1], four_points[2]], \
             [four_points[2], four_points[3]], [four_points[3], four_points[0]]], \
       color=(255,255,255)) \
    .save("llr_debug_3")

    return four_points