def parse_image(im, model, channel): """Parses graph image downloaded from innerfidelity.com""" # Find graph edges v_lines = ImageGraphParser.find_lines(im, 'vertical', line_color=(204, 204, 204)) h_lines = ImageGraphParser.find_lines(im, 'horizontal', line_color=(204, 204, 204)) h_lines = np.array(h_lines) # Crop by left and right edges box = (v_lines[0], h_lines[0], v_lines[-1], im.size[1]) im = im.crop(box) h_lines -= h_lines[ 0] # Cropped to first line, subtract distance from all lines # Add missing horizontal lines 115 - 55 deltas = [] for i in range(1, len(h_lines)): deltas.append(h_lines[i] - h_lines[i - 1]) delta = max(deltas, key=deltas.count) _h_lines = list(h_lines[:1]) for _ in range(12): # First line + 12 additional lines # Estimate where the line should be estimate = _h_lines[-1] + delta # Get original lines which are at most 1 pixel away from the estimate originals = h_lines[np.abs(np.array(h_lines) - estimate) <= 1] if len(originals): # Original line found, use it estimate = originals[0] # Add new line _h_lines.append(estimate) h_lines = _h_lines # Crop bottom box = (0, 0, im.size[0], h_lines[-1]) im = im.crop(box) px_a_max = 0 px_a_min = h_lines[-1] #im.show() # X axis f_min = 20 f_max = 20000 f_step = (f_max / f_min)**(1 / im.size[0]) f = [f_min] for _ in range(1, im.size[0]): f.append(f[-1] * f_step) # Y axis a_max = 115 a_min = 55 a_res = (a_max - a_min) / (px_a_min - px_a_max) # Colors color_left = (79, 129, 189) color_right = (119, 119, 119) _im = im.copy() inspection = _im.load() amplitude = [] # Iterate each column for x in range(im.size[0]): pxs = [] # Graph pixels # Iterate each row (pixel in column) for y in range(im.size[1]): # Convert read RGB pixel values and convert to HSV rgba = im.getpixel((x, y)) r, g, b = rgba[:3] # Graph pixels are colored if (channel == 'left' and (r, g, b) == color_left) or (channel == 'right' and (r, g, b) == color_right): pxs.append(float(y)) else: p = im.getpixel((x, y)) inspection[x, y] = (int(0.3 * p[0]), int(255 * 0.7 + 0.3 * p[1]), int(0 + 0.3 * p[2])) if not pxs: # No graph pixels found on this column amplitude.append(None) else: # Mean of recorded pixels v = np.mean(pxs) # Convert to dB value v = a_max - v * a_res amplitude.append(v) # Inspection image draw = ImageDraw.Draw(_im) x0 = np.log(30 / f_min) / np.log(f_step) x1 = np.log(10000 / f_min) / np.log(f_step) y_0 = px_a_max + 10 / a_res y_1 = px_a_min - 10 / a_res draw.rectangle(((x0, y_0), (x1, y_1)), outline='magenta') draw.rectangle(((x0 + 1, y_0 + 1), (x1 - 1, y_1 - 1)), outline='magenta') # Create frequency response fr = FrequencyResponse(model, f, amplitude) fr.interpolate() fr.center() return fr, _im
def parse_image(im, model, px_top=800, px_bottom=4400, px_left=0, px_right=2500): """Parses graph image downloaded from innerfidelity.com""" # Crop out everything but graph area (roughly) box = (px_left, px_top, im.size[0] - px_right, im.size[1] - px_bottom) im = im.crop(box) #im.show() # Find graph edges v_lines = ImageGraphParser.find_lines(im, 'vertical') h_lines = ImageGraphParser.find_lines(im, 'horizontal') # Crop by graph edges box = (v_lines[0], h_lines[0], v_lines[1], h_lines[1]) im = im.crop(box) #im.show() # X axis f_min = 10 f_max = 20000 f_step = (f_max / f_min)**(1 / im.size[0]) f = [f_min] for _ in range(1, im.size[0]): f.append(f[-1] * f_step) # Y axis a_max = 30 a_min = -20 a_res = (a_max - a_min) / im.size[1] _im = im.copy() pix = _im.load() amplitude = [] y_legend = 40 / 50 * im.size[1] x0_legend = np.log(70 / f_min) / np.log(f_step) x1_legend = np.log(1000 / f_min) / np.log(f_step) # Iterate each column for x in range(im.size[0]): pxs = [] # Graph pixels # Iterate each row (pixel in column) for y in range(im.size[1]): if y > y_legend and x0_legend < x < x1_legend: # Skip pixels in the legend box continue # Convert read RGB pixel values and convert to HSV h, s, v = colorsys.rgb_to_hsv( *[v / 255.0 for v in im.getpixel((x, y))]) # Graph pixels are colored if 0.7 < s < 0.9 and 20 / 360 < h < 30 / 360: pxs.append(float(y)) else: p = im.getpixel((x, y)) pix[x, y] = (int(0.3 * p[0]), int(255 * 0.7 + 0.3 * p[1]), int(0.3 * p[2])) if not pxs: # No graph pixels found on this column amplitude.append(None) else: # Mean of recorded pixels v = np.mean(pxs) # Convert to dB value v = a_max - v * a_res amplitude.append(v) # Inspection image draw = ImageDraw.Draw(_im) x0 = np.log(20 / f_min) / np.log(f_step) x1 = np.log(10000 / f_min) / np.log(f_step) draw.rectangle(((x0, 10 / a_res), (x1, 40 / a_res)), outline='magenta') draw.rectangle(((x0 + 1, 10 / a_res + 1), (x1 - 1, 40 / a_res - 1)), outline='magenta') fr = FrequencyResponse(model, f, amplitude) fr.interpolate() fr.center() return fr, _im