Пример #1
0
def fine_dewarp(im, lines):
    im_h, im_w = im.shape[:2]

    debug = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)
    points = []
    y_offsets = []
    for line in lines:
        if len(line) < 10 or abs(line.fit_line().angle()) > 0.001: continue
        line.fit_line().draw(debug, thickness=1)
        base_points = np.array([letter.base_point() for letter in line.inliers()])
        median_y = np.median(base_points[:, 1])
        y_offsets.append(median_y - base_points[:, 1])
        points.append(base_points)

        for underline in line.underlines:
            mid_contour = (underline.top_contour() + underline.bottom_contour()) / 2
            all_mid_points = np.stack([
                underline.x + np.arange(underline.w), mid_contour,
            ])
            mid_points = all_mid_points[:, ::4]
            points.append(mid_points)

        for p in base_points:
            pt = tuple(np.round(p).astype(int))
            cv2.circle(debug, (pt[0], int(median_y)), 2, lib.RED, -1)
            cv2.circle(debug, pt, 2, lib.GREEN, -1)
    cv2.imwrite('points.png', debug)

    points = np.concatenate(points)
    y_offsets = np.concatenate(y_offsets)
    mesh = np.mgrid[:im_w, :im_h].astype(np.float32)
    xmesh, ymesh = mesh

    # y_offset_interp = interpolate.griddata(points, y_offsets, xmesh, ymesh, method='nearest')
    # y_offset_interp = y_offset_interp.clip(-5, 5)
    # mesh[1] += y_offset_interp  # (mesh[0], mesh[1], grid=False)

    y_offset_interp = interpolate.SmoothBivariateSpline(
        points[:, 0], points[:, 1], y_offsets.clip(-3, 3),
        s=4 * points.shape[0]
    )
    ymesh -= y_offset_interp(xmesh, ymesh, grid=False).clip(-3, 3)

    conv_xmesh, conv_ymesh = cv2.convertMaps(xmesh, ymesh, cv2.CV_16SC2)
    out = cv2.remap(im, conv_xmesh, conv_ymesh,
                    interpolation=cv2.INTER_LINEAR,
                    borderValue=np.median(im)).T
    cv2.imwrite('corrected.png', out)

    debug = cv2.cvtColor(out, cv2.COLOR_GRAY2BGR)
    for line in lines:
        base_points = np.array([letter.base_point() for letter in line.inliers()[1:-1]])
        base_points[:, 1] -= y_offset_interp(base_points[:, 0], base_points[:, 1], grid=False)
        Line.fit(base_points).draw(debug, thickness=1)
    cv2.imwrite('corrected_line.png', debug)

    return out
Пример #2
0
    def fit_line(self):
        if self.model_line is None:
            if len(self) <= 3:
                self.model_line = Line.fit(self.base_points())
            else:
                model, inliers = ransac(self.base_points(), TextLine.LineModel,
                                        3, 4)
                self.model_line = model.params
                self._line_inliers = list(
                    itertools.compress(self.letters, inliers))

        return self.model_line
Пример #3
0
def vanishing_point(lines, v0, O):
    C0 = lines[-1] if v0[1] < 0 else lines[0]
    others = lines[:-1] if v0[1] < 0 else lines[1:]

    domain = np.linspace(C0.left(), C0.right(), N_LONGS + 2)[1:-1]
    C0_points = np.array([domain, C0.model(domain)]).T
    longitudes = [Line.from_points(v0, p) for p in C0_points]

    lefts = [longitudes[0].text_line_intersect(line)[0] for line in others]
    rights = [longitudes[-1].text_line_intersect(line)[0] for line in others]
    valid_mask = [line.left() <= L and R < line.right() \
                   for line, L, R in zip(others, lefts, rights)]

    valid_lines = [C0] + compress(others, valid_mask)
    derivs = [line.model.deriv() for line in valid_lines]
    print('valid lines:', len(others))

    convergences = []
    for longitude in longitudes:
        intersects = [
            longitude.text_line_intersect(line) for line in valid_lines
        ]
        tangents = [Line.from_point_slope(p, d(p[0])) \
                    for p, d in zip(intersects, derivs)]
        convergences.append(Line.best_intersection(tangents))

    # x vx + y vy + f^2 = 0
    # m = -vx / vy
    # b = -f^2 / vy

    L = Line.fit(convergences)
    # shift into O-origin coords
    L_O = L.offset(-O)
    vy = -(f**2) / L_O.b
    vx = -vy * L_O.m
    v = np.array((vx, vy)) + O

    debug = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR)
    for t in tangents:
        t.draw(debug, color=RED)
    for longitude in longitudes:
        longitude.draw(debug)
    L.draw(debug, color=GREEN)
    lib.debug_imwrite('vanish.png', debug)

    return v, f, L
Пример #4
0
 def estimate(self, data):
     self.params = Line.fit(data)
     return True