簡體   English   中英

拉直B樣條曲線

[英]Straighten B-Spline

我已經插入了樣條曲線,以使圖像中的像素數據具有我想拉直的曲線。 我不確定哪種工具適合解決此問題。 有人可以推薦一種方法嗎?

這是我得到樣條的方式:

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()

我的更廣泛的項目是遵循一種新的方法中概述的方法, 該方法可以使樣式化文檔中的彎曲文本行變直 該文章在查找描述彎曲文本的線​​時進行了詳細介紹,但在涉及到拉直曲線時要少得多。 我很難想象我看到的關於矯直的唯一參考是抽象的:

找到曲線上某個點的法線與垂直線之間的角度,最后訪問文本上的每個點並旋轉它們相應的角度。

我還在python中發現了圖像的幾何變形 ,這似乎很有希望。 如果可以校正樣條曲線,我認為這將允許我設置仿射變換要映射到的目標點范圍。 不幸的是,我還沒有找到一種方法來糾正我的樣條並對其進行測試。

最后, 程序實現了拉直樣條曲線的算法,但是關於該算法的論文在收費壁壘后面,我無法理解javascript。

基本上,我迷路了,需要指針。

更新

仿射變換是我不知道如何開始探索的唯一方法,因此自發布以來我一直在努力。 我根據b樣條曲線上各點之間的歐式距離對曲線進行了近似校正,從而生成了一組目標坐標。

從最后一個代碼塊停止的地方:

# 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)

我目前掛在仿射變換的錯誤上( scipy.spatial.qhull.QhullError: QH6154 Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point) ),但我不確定是否是因為我要如何輸入數據而出現問題,或者是因為我濫用轉換來進行投影。

使用scipy.spatial.ConvexHull時,您遇到相同的錯誤。 首先,讓我解釋一下我的項目:我想做的是從背景中區分人物(圖像遮罩)。 在我的代碼中,首先讀取圖像和Trimap,然后根據Trimap將原始圖像分割為前景,bakground和未知像素。 這是男女同校的一部分:

img = scipy.misc.imread('sweater_black.png') #color_image

trimap = scipy.misc.imread('sw_trimap.png', flatten='True') #trimap

bg = trimap == 0 #background

fg = trimap == 255 #foreground

unknown = True ^ np.logical_or(fg,bg) #unknown pixels

fg_px = img[fg] #here i got the rgb value of the foreground pixels,then send them to the ConvexHull

fg_hull = scipy.spatial.ConvexHull(fg_px)

但是我在這里出錯了,所以我檢查了fg_px的數組,然后發現這個數組是n * 4。 這意味着我發送給ConvexHull的每個標量都有四個值。 但是,ConvexHUll的輸入應為3維。 我發現錯誤,並發現輸入的彩色圖像是32位(RGB通道和Alpha通道),這意味着它具有Alpha通道。 將圖像傳輸到24位(這意味着僅rgb通道)后,代碼起作用。

一句話,ConvexHull的輸入應為b * 4,因此請檢查您的輸入數據! 希望這對你有用〜

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM