示例#1
0
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
示例#2
0
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