Ich habe einen Spline interpoliert, um Pixeldaten aus einem Bild mit einer Kurve anzupassen, die ich gerade begradigen möchte. Ich bin mir nicht sicher, welche Tools zur Lösung dieses Problems geeignet sind. Kann jemand einen Ansatz empfehlen?Begradigen B-Spline
Hier ist, wie ich meine Spline bekommen:
import numpy as np
from skimage import io
from scipy import interpolate
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors
import networkx as nx
# Read a skeletonized image, return an array of points on the skeleton, and divide them into x and y coordinates
skeleton = io.imread('skeleton.png')
curvepoints = np.where(skeleton==False)
xpoints = curvepoints[1]
ypoints = -curvepoints[0]
# reformats x and y coordinates into a 2-dimensional array
inputarray = np.c_[xpoints, ypoints]
# runs a nearest neighbors algorithm on the coordinate array
clf = NearestNeighbors(2).fit(inputarray)
G = clf.kneighbors_graph()
T = nx.from_scipy_sparse_matrix(G)
# sorts coordinates according to their nearest neighbors order
order = list(nx.dfs_preorder_nodes(T, 0))
xx = xpoints[order]
yy = ypoints[order]
# Loops over all points in the coordinate array as origin, determining which results in the shortest path
paths = [list(nx.dfs_preorder_nodes(T, i)) for i in range(len(inputarray))]
mindist = np.inf
minidx = 0
for i in range(len(inputarray)):
p = paths[i] # order of nodes
ordered = inputarray[p] # ordered nodes
# find cost of that order by the sum of euclidean distances between points (i) and (i+1)
cost = (((ordered[:-1] - ordered[1:])**2).sum(1)).sum()
if cost < mindist:
mindist = cost
minidx = i
opt_order = paths[minidx]
xxx = xpoints[opt_order]
yyy = ypoints[opt_order]
# fits a spline to the ordered coordinates
tckp, u = interpolate.splprep([xxx, yyy], s=3, k=2, nest=-1)
xpointsnew, ypointsnew = interpolate.splev(np.linspace(0,1,270), tckp)
# prints spline variables
print(tckp)
# plots the spline
plt.plot(xpointsnew, ypointsnew, 'r-')
plt.show()
Mein breiter angelegtes Projekt ist das Konzept in A novel method for straightening curved text-lines in stylistic documents skizziert zu folgen. Dieser Artikel ist ziemlich detailliert darin, die Linie zu finden, die gekrümmten Text beschreibt, aber viel weniger, wenn es darum geht, die Kurve zu glätten. Ich habe Mühe, die einzige Referenz zu visualisieren zu Begradigung, dass ich sehe, in der Zusammenfassung ist:
den Winkel zwischen der Normalen an einem Punkt auf der Kurve finden und die vertikalen Linie und schließlich jeden Punkt auf dem Text besuchen und drehen durch ihre entsprechenden Winkel.
Ich fand auch Geometric warp of image in python, die vielversprechend scheint. Wenn ich den Spline korrigieren könnte, würde ich damit eine Reihe von Zielpunkten für die affine Transformation festlegen. Leider habe ich keinen Ansatz gefunden, um meinen Spline zu korrigieren und zu testen.
Schließlich this Programm implementiert einen Algorithmus, um Splines zu begradigen, aber das Papier auf dem Algorithmus ist hinter einer Pay-Wand und ich kann den Javascript nicht verstehen.
Grundsätzlich bin ich verloren und brauche Zeiger.
aktualisieren
Die affine Transformation war der einzige Ansatz, den ich eine Idee hatte, wie die Erkundung zu beginnen, also habe ich auf, dass gearbeitet, seit ich geschrieben. Ich habe eine Reihe von Zielkoordinaten erstellt, indem ich eine ungefähre Entzerrung der Kurve basierend auf dem euklidischen Abstand zwischen Punkten auf meinem B-Spline durchgeführt habe.
Von dort, wo der letzten Codeblock aus links:
# calculate euclidian distances between adjacent points on the curve
newcoordinates = np.c_[xpointsnew, ypointsnew]
l = len(newcoordinates) - 1
pointsteps = []
for index, obj in enumerate(newcoordinates):
if index < l:
ord1 = np.c_[newcoordinates[index][0], newcoordinates[index][1]]
ord2 = np.c_[newcoordinates[index + 1][0], newcoordinates[index + 1][1]]
length = spatial.distance.cdist(ord1, ord2)
pointsteps.append(length)
# calculate euclidian distance between first point and each consecutive point
xpositions = np.asarray(pointsteps).cumsum()
# compose target coordinates for the line after the transform
targetcoordinates = [(0,0),]
for element in xpositions:
targetcoordinates.append((element, 0))
# perform affine transformation with newcoordinates as control points and targetcoordinates as target coordinates
tform = PiecewiseAffineTransform()
tform.estimate(newcoordinates, targetcoordinates)
ich derzeit bin auf Fehler bei den affinen Transformation aufgehängt (scipy.spatial.qhull.QhullError: QH6154 Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point)
), aber ich bin mir nicht sicher, ob es wegen eines Problems ist, mit wie Ich füttere die Daten oder weil ich die Transformation missbrauche, um meine Projektion zu machen.
Suchen Sie nach einer Transformation, die Ihren Spline auf eine bestimmte gerade Linie projizieren oder versuchen Sie eine gerade Linie aus einer gegebenen Transformation zu bestimmen? Hoffnung, die Sinn macht. – DrBwts
Wenn ich Ihre Frage richtig verstehe, möchte ich die Transformation finden, die meinen Spline auf eine gerade Linie projiziert. – Tric
Und Sie haben die Gleichung dieser Linie? – DrBwts