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