Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
11 kB
2
Indexable
import math
import pytesseract
import cv2
import numpy as np
# from matplotlib import pyplot as plt
def filter_conts(letters, img):
    # cv2.imshow("It", img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    # return 0
    # fig = plt.figure()
    result ={"ok": False,
             "angle": [],
             "points": []
             }
    c_x, c_y = img.shape[:2]
    c_x//=2
    c_y//=2
    plt.clf()
    # print(letters)
    # print(len(letters))
    x = np.array(letters)[:,0]
    # print(x)
    y = np.array(letters)[:,1]
    # print(y)
    colors = ['red', 'green', 'blue']
    i = 1
    plt.scatter(x, y)
    plt.gca().set_ylim(max(y), min(y))
    plt.gca().yaxis.grid(False)
    # print()
    xy_r = []
    a = {"points":[],
         "center": [],
         "r": []}
    # print(len(letters))
    points = letters
    g = get_objects(letters, a)
    print("end ", g, end='\n')
    # print(g["center"][0])
    mx = -float('inf')
    for i in range(len(g["points"])):
        x, y = g["center"][i]
        r = g["r"][i]
        check = check_zones(g["points"][i], c_x, c_y)
        # print("Входящий массив: ", g["points"][i])
        # print(check)
        if check["ok"]:
            # print("g[] ",g["points"][i])
            # exit()
            x,y = g["center"][i]
            r = g["r"][i]
            result["points"].append(check["message"]["points"])
            # print(len(check["message"]["points"]))
            result["angle"].append(check["message"]["angle"])
            result["ok"] = True
            # print(x,y, r, check["message"]["angle"])

            # M = cv2.get\rpAffine(img, M, (c_x, c_y))
            c = plt.Circle((x, y), r, color='green', fill=False)
            plt.gca().add_patch(c)

        else:

            c = plt.Circle((x, y), r, color='red', fill=False)
            plt.gca().add_patch(c)

    # print("ews ", result)
    # cv2.imshow("It", img)
    # plt.show()
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    # count_row(points)

    return result
def check_zones(points, c_x, c_y):
    check = {"ok":None,
             "message":None
            }
    # print(points)
    # return False
    vectors = []
    for i in range(len(points)):

        x0,y0,w,h = points[i]
        x0 = (x0 + w//2)
        y0 = (y0 + h//2)
        c = 0
        for j in range(i+1, len(points)):
            x1,y1,w1,h1,*_ = points[j]
            dx = (x1 + w1//2 ) - x0
            dy = (y1 + h1//2 ) - y0
            d = int(((dx)**2+(dy)**2)**0.5)
            if dx == 0:
                k = b = 0
            else:
                k = round(dy/dx, 2)
                b = y1 - k*x1
            if 7 < d < 75:
                c+=1
                # if [x0,y0,dx,dy,k, int(b)] not in vectors:
                # plt.plot([x0,x1],[y0,y1])
                vectors.append([x0,y0,dx,dy,k, int(b), k//0.12*0.12]) ## Координаты вектора и точек.
    # vectors.sort(key=lambda x: x[5])
    # plt.show()
    if len(vectors) < 3:
        check["ok"] = False
        check["message"] = {"vects": len(vectors)}
        return check
    # print(vectors)
    # exit()
    # print("Длина: ", len(vectors))
    vectors = sorted(vectors, key = lambda x: x[4])
    vectors = is_zero(vectors)
    k_arr = list(np.array(vectors)[:,6])
    arr = []
    all_c = 0
    mx = -1
    mx_c = -1
    for num in (set(k_arr)):
        c = k_arr.count(num)
        arr.append([num, c])
        if mx_c < c:
            mx_c = c
            mx = num
    arr = []
    # print("mx ", mx)
    for v in vectors:
        x,y,w,h,*_ = v
        if v[-1] == mx:
            arr.append(v)
            # plt.plot([x, x + w],[y, y + h])
    # print(np.array(arr))
    cur = arr[0][1]
    vectors = arr
    i = 0

    matrix = np.array(vectors)
    # print(matrix)
    vect_xy = (matrix[:, :2]).tolist()
    # print(vect_xy)

    # exit()
    vects_ed = []
    for v in vect_xy:
        if vect_xy.count(v) == 1:
            vects_ed.append(list(map(int, v)))
    # print(vects_ed)
    # print(vectors[0])

    k_sum = 0
    for v in vectors:
        k_sum += v[4]
    # print('_____________________________________________ ')
    # print(vectors)
    # print(k_sum/len(vectors))
    angle = int(math.atan(k_sum/len(vectors))*180/math.pi)
    # print("angle ", angle)

    vectors.sort(key = lambda x:x[1])
    # print("V ",vectors)
    for v in vectors:
        xy = v[:2]
        if xy not in vects_ed:
            # print(v)
            plt.plot([v[0], v[0] + v[2]], [v[1], v[1] + v[3]])
    # plt.show()
    points = []
    # f_p = []
    for v in vectors:
        x0,y0 = v[:2]
        x1,y1 = x0+v[2], y0+v[3]
        points.append([x0,y0, 1,0])
        points.append([x1, y1, 1, 0])
    # plt.gca().set_ylim(max(y), min(y))  # Устанавливаем обратное направление для оси Y
    points = sorted(points, key=lambda x: x[0])
    # print("P ", points)
    points = rotate(points, -angle, c_x, c_y)
    # print(angle)
    # points = rt(points, angle,c_x, c_y)
    # print("prt ", points)
    y_arr = list(np.array(points)[:, 1])
    rows = count_p(y_arr)
    c_rows = len(rows)
    points.sort(key = lambda x:x[1])
    # plt.show()
    print("True ", c_rows)
    print("Строки: ", rows)
    print("angle ", angle)
    if 0 < c_rows < 10:
        print("True ", c_rows)
        print("Строки: ", rows)
        print("angle ", angle)
        check["ok"] = True
        check["message"] = {
            "angle" : angle,
            "rows" : len(rows),
            "points": points
        }
        return check
    else:
        check["ok"] = False
        check["message"] = {
            "rows": len(rows),
            "angle": angle
        }

        return check


    # return {"points": points,
    #         "angle": angle,
    #         "plt": plt
    #         }
def is_zero(arr):
    arr = sorted(arr, key = lambda x: x[4], reverse=True)
    # print(arr)
    if arr[0][4] != 0.0 or arr[-1][4] != 0.0:
        arr = filter(lambda x: x[4] != 0.0, arr)
    return sorted(arr, key = lambda x: x[5])
def Forel(points, xy, st_x, st_y, r = 400, T = [], plt = None, color = 'red'):
    # plt.show()
    if r<100:
        r = 120
    d_arr = []
    for point in points:
        x, y, w, h = point
        # print(point)
        d = ((x-st_x)**2 + (y-st_y)**2)**0.5
        if 0 < d <=r and [x, y] not in d_arr:
            d_arr.append([x, y, w,h])
    p = grav_cen(d_arr)
    print(p)
    if p != None:
        # d = p[0]
        x, y = p

        if (st_x == x and st_y==y) or (x,y) in xy:
            # print("Конец ", r)
            return {"center":(x,y),
                    "r": r,
                     "points": d_arr
                     }
        r-=50
        xy.append((x, y))
        return Forel(points, xy, x, y, r, T, plt, color)

    print("None ", r)

    return {"center":(st_x,st_y),
            "r":r,
            "points": d_arr

            }
def grav_cen(points):
    num_points = len(points)

    if num_points == 0:
        return None

    sum_x = sum(point[0] for point in points)
    sum_y = sum(point[1] for point in points)

    center_x = sum_x / num_points
    center_y = sum_y / num_points

    return center_x, center_y
def minD(arr):
    mx = 0
    rt = 0
    for a in arr:
        if a[0] > mx and a[0]!=0:
            rt = a
            mx = a[0]
    return rt
def del_points(points, arr):
    for a in arr:
        x,y = a[:2]
        for point in points:
            x1,y1 = point[:2]
            if x == x1 and y == y1:
                points.remove(point)
    return points
def get_objects(letters, objects):
    if len(letters) < 10:
        # print(objects)
        return objects
    x, y = letters[0][:2]
    f = Forel(letters,[(x,y)], x, y, 250, [], plt)
    if f["points"] == []:
        return get_objects(letters[1:], objects)
    else:
        objects["points"].append(f["points"])
        # objects["vectors"].append(f["points"])
        # print("centr ", f["center"])
        objects["center"].append(f["center"])
        objects["r"].append(f["r"])
        letters = del_points(letters, f["points"])
    # c = plt.Circle(f["center"], f["r"], color='blue', fill=False)
    # plt.gca().add_patch(c)
    # plt.show()
    # print("Длина после удаления: ",len(letters))
        return get_objects(letters, objects)
def rt(points, alfa,d_x,d_y):
    # alfa = angle*math.pi/180
    ret_arr = []
    for point in points:
        x,y,w,h = point
        # x = x - d_x
        # y = y - d_y
        x1 = int(d_x + (x - d_x) * math.cos(alfa) + (y - d_y) * math.sin(alfa))
        y1 = int(d_y - (x - d_x) * math.sin(alfa) + (y - d_y) * math.cos(alfa))
        ret_arr.append([x1,y1,w,h])
    return ret_arr
def rotate(points, alfa_new = 1 , mx = 0, my = 0, ret_obj = False):
    ret = []
    retx = []
    rety =[]
    for point in points:
        x = point[0] - mx
        y = point[1] - my
        # alfa = alfa_new*math.pi/180
        w = point[2]
        h = point[3]
        tan_wh = h/w
        if x == 0: tan = 0
        else: tan = y/x
        alfa_wh = math.atan(tan_wh)
        alfa_wh_rad = alfa_new*math.pi/180
        one_wh = w/math.cos(alfa_wh)
        new_w = int(one_wh * math.cos(alfa_wh+alfa_wh_rad))
        new_h = int(one_wh * math.sin(alfa_wh+alfa_wh_rad))
        # print("w, h", new_w, new_h)

        alfa = math.atan(tan)
        alfa_rad = alfa_new * math.pi / 180
        one = x/math.cos(alfa)
        newx = int(one * math.cos(alfa + alfa_rad))
        newy = int(one * math.sin(alfa + alfa_rad))
        if ret_obj:
            retx.append(newx)
            rety.append(newy)

        else:
            ret.append(([newx + mx + w, newy + my + h, new_w, new_h]))
    if ret_obj:
        return {
            "x": retx,
            "y": rety
        }
    return ret
def count_p(arr, img = None):
    image = cv2.imread("res.jpg")
    ret_arr = []
    for i in range(15):
        ret_arr.append([])
    arr = sorted(arr)
    # print("sore ",arr)
    n = 0
    s_arr = list(arr)
    row_c = 0
    # ret_arr.append([arr[0]])
    cur = -float('inf')
    # print(ret_arr)
    arr.append(0)
    for i in range(len(s_arr) - 1):
        if abs(s_arr[i] - s_arr[i+1]) < 10:

            ret_arr[row_c].append(s_arr[i])
        else:
            row_c+=1

    # print(ret_arr)
    ret_arr = list(filter(lambda x: len(x)>2, ret_arr))

    # print("Количество строк", len(ret_arr))
    print("ret ",ret_arr)

    return ret_arr