-
Notifications
You must be signed in to change notification settings - Fork 0
/
mark_plot.py
56 lines (43 loc) · 1.96 KB
/
mark_plot.py
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
__author__ = 'Siarshai'
from math import sqrt
from PIL import ImageDraw
import numpy as np
from find_crosses import find_crosses
import utils_general
from utils_general import convert_image_to_data_buffer
from utils_draw import draw_point_plot
def prepare_poly_interpolated_plot(x_list, y_list, pts_number, f_poly_power=-1):
if len(x_list) != len(y_list):
raise ValueError("ERROR: x_list and y_list should have equal length to interpolate")
if f_poly_power < 1:
f_poly_power = int(1 + sqrt(len(x_list)))
if utils_general.is_debug:
print("Number of x points: {}, poly max degree: {}".format(len(x_list), f_poly_power))
f_poly_coeffs = np.polyfit(x_list, y_list, f_poly_power)
f_poly = np.poly1d(f_poly_coeffs)
xp = np.linspace(x_list[0], x_list[-1], pts_number)
yp = f_poly(xp)
return xp, yp
def mark_plot(image, f_poly_power = -1, plot_pts_size=50):
"""
Searches for plot axes and point marks then constructs a poly to interpolate a diagram
:param image: image to operate on
:param f_poly_power: one can specifically set power of interpolation poly
:param plot_pts_size: number of points in drawn plot
:return:
"""
draw = ImageDraw.Draw(image)
width = image.size[0]
height = image.size[1]
pix = image.load()
image_data = convert_image_to_data_buffer(pix, width, height, channels=3)
x_axis_cross, y_axis_cross, crosses_result_list = find_crosses(image_data)
#This step is crucial for further poly interpolation and diagram drawing
crosses_result_list.sort(reverse=True, key=lambda x: x[0])
x_list = [point[0] for point in crosses_result_list]
y_list = [point[1] for point in crosses_result_list]
xp, yp = prepare_poly_interpolated_plot(x_list, y_list, plot_pts_size, f_poly_power)
draw_point_plot(draw, xp, yp, plot_pts_size)
draw.point((x_axis_cross, y_axis_cross), (255, 0, 0))
for pt in crosses_result_list:
draw.point((pt[0], pt[1]), (0, 255, 0))