我有兩個形狀或坐標系,我希望能夠將點從一個系統轉換到另一個系統。
我發現如果形狀是四邊形并且我有 4 對對應點,那么我可以計算一個變換矩陣,然后使用該矩陣計算任何點Shape B到它的對應坐標上Shape A。

這是進行此計算的作業python代碼:
import numpy as np
import cv2
shape_a_points = np.array([
[0.6, 0],
[1, 0.75],
[0.8, 1],
[0.5, 0.6]
], dtype="float32")
shape_b_points = np.array([
[0, 0],
[1, 0],
[1, 1],
[0, 1],
], dtype="float32")
test_points = [0.5, 0.5]
matrix = cv2.getPerspectiveTransform(shape_b_points, shape_a_points)
print(matrix)
result = cv2.perspectiveTransform(np.array([[test_points]], dtype="float32"), matrix)
print(result)
如果您運行此代碼,您將看到 (0.5, 0.5) on Shape B(正中間)的測驗點顯示為 (0.73, 0.67) on Shape A,這在視覺上看起來是正確的。
但是,如果形狀更復雜,我該怎么辦。比如4 N個頂點,4 N對對應點?或者更復雜的是,如果形狀中有曲線怎么辦?
例如:

uj5u.com熱心網友回復:
感謝@christoph-rackwitz 為我指明了正確的方向。
我發現使用 OpenCV 進行轉換的效果非常好ThinPlateSplineShapeTransformer。
下面是我的示例腳本。請注意,我有 7 對點。“匹配項”只是 7 個串列(告訴腳本點 #1 從Shape A匹配項到點 #1 從Shape B...等..)
import numpy as np
import cv2
number_of_points = 7
shape_a_points = np.array([
[0.6, 0],
[1, 0.75],
[0.8, 1],
[0.5, 0.6],
[0.75, 0],
[1, 0],
[1, 0.25]
], dtype="float32").reshape((-1, number_of_points, 2))
shape_b_points = np.array([
[0, 0],
[1, 0],
[1, 1],
[0, 1],
[0.25, 0],
[0.5, 0],
[0.75, 0]
], dtype="float32").reshape((-1, number_of_points, 2))
test_points = [0.5, 0.5]
matches = [cv2.DMatch(i, i, 0) for i in range(number_of_points)]
tps = cv2.createThinPlateSplineShapeTransformer()
tps.estimateTransformation(shape_b_points, shape_a_points, matches)
M = tps.applyTransformation(np.array([[test_points]], dtype="float32"))
print(M[1])
我不知道你為什么需要重塑陣列;“你就是這樣做”,否則它將不起作用。
如果有人想使用它,我也將它放入一個簡單的類中:
import cv2
import numpy as np
class transform:
def __init__(self, points_a, points_b):
assert len(points_a) == len(points_b), "Number of points in set A and set B should be same count"
matches = [cv2.DMatch(i, i, 0) for i in range(len(points_a))]
self.tps = cv2.createThinPlateSplineShapeTransformer()
self.tps.estimateTransformation(np.array(points_b, dtype="float32").reshape((-1, len(points_a), 2)),
np.array(points_a, dtype="float32").reshape((-1, len(points_a), 2)), matches)
def transformPoint(self, point):
result = self.tps.applyTransformation(np.array([[point]], dtype="float32"))
return result[1][0][0]
uj5u.com熱心網友回復:
如果兩個形狀通過透視變換相關,那么任何四個點都會導致相同的變換,至少只要它們中沒有一個是共線的。從理論上講,您可以選擇任意四個這樣的點,其余的應該就可以了。
在實踐中,數字方面的考慮可能會發揮作用。如果您選擇彼此非常接近的點,那么它們位置的小錯誤會導致遠離這些點的更大錯誤。您可能可以進行一些涉及錯誤間隔的復雜分析,但根據經驗,我會嘗試在轉換的輸入端和輸出端的任意兩點之間瞄準較大的距離。
我在 Math Exchange 上的回答解釋了一些用于定義點對的透視變換的計算。它可能有助于理解數字 4 的來源。
如果您有超過 4 對點,并且使用其中任何四個定義轉換并不能正確轉換其余點,那么您很可能處于其他兩個用例之一。
要么您確實在尋找透視轉換,但輸入資料較差。您可能有來自特征檢測的位置,并且可能不精確。有些特征甚至可能是間接匹配的。因此,在這種情況下,您將尋找最佳轉換來描述具有小錯誤的資料。您的問題聽起來不像是您的用例,所以我不會詳細說明。
我們的你有一個不是透視轉換的轉換。特別是任何將直線變成彎曲曲線或反之亦然的東西都不再是透視變換。您可能正在尋找其他型別的變換,或類似分段射影變換的東西。在不了解您的用例的情況下,很難為此建議一類好的轉換。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/420205.html
標籤:
上一篇:為什么我在app.yaml中包含app_engine_apis后仍然收到警告?
下一篇:OpenCV深度繪圖
