この質問は、2セットのポイント間の変換に関連しています。ただし、これはより適切に指定され、いくつかの仮定が追加されています。
要素画像といくつかのモデルがあります。
両方で輪郭を検出しました
contoursModel0, hierarchyModel = cv2.findContours(model.copy(), cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE);
contoursModel = [cv2.approxPolyDP(cnt, 2, True) for cnt in contoursModel0];
contours0, hierarchy = cv2.findContours(canny.copy(), cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE);
contours = [cv2.approxPolyDP(cnt, 2, True) for cnt in contours0];
次に、各輪郭を互いに一致させました
modelMassCenters = [];
imageMassCenters = [];
for cnt in contours:
for cntModel in contoursModel:
result = cv2.matchShapes(cnt, cntModel, cv2.cv.CV_CONTOURS_MATCH_I1, 0);
if(result != 0):
if(result < 0.05):
#Here are matched contours
momentsModel = cv2.moments(cntModel);
momentsImage = cv2.moments(cnt);
massCenterModel = (momentsModel['m10']/momentsModel['m00'],
momentsModel['m01']/momentsModel['m00']);
massCenterImage = (momentsImage['m10']/momentsImage['m00'],
momentsImage['m01']/momentsImage['m00']);
modelMassCenters.append(massCenterModel);
imageMassCenters.append(massCenterImage);
一致する輪郭は、フィーチャのようなものです。
ここで、この2つのポイントセット間の変換を検出したいと思います。前提条件:要素は剛体であり、回転、変位、およびスケールの変更のみです。
一部の機能は、それらを排除する方法が検出されない可能性があります。私はかつて使用cv2.findHomography
したことがあり、2つのベクトルを取り、いくつかのミスマッチがあってもそれらの間のホモグラフィを計算します。
cv2.getAffineTransformation
たった3つのポイント(ミスマッチに対処できません)を取ります、そしてここで私は複数の機能を持っています。私の前の質問の答えは、この変換を計算する方法を示していますが、ミスマッチは取りません。また、アルゴリズムからある程度の品質レベルを返すことも可能だと思います(残りの部分からいくつかの変換を計算した後、不一致のポイントの数をチェックすることによって)
そして最後の質問:変換を計算するためにすべてのベクトル点を取るべきですか、それともこの形状の質量中心のみを特徴として扱うべきですか?
それを示すために、簡単な画像を追加しました。緑の機能は、赤の悪い一致の良い一致です。ここで、一致は3つの緑の機能から計算する必要があり、赤の不一致は一致の品質に影響を与えるはずです。
私は今のところ理解したソリューションの断片を追加しています(しかし、それははるかにうまくいく可能性があると思います):
for i in range(0, len(modelMassCenters) - 1):
for j in range(i + 1, len(modelMassCenters) - 1 ):
x1, y1 = modelMassCenters[i];
x2, y2 = modelMassCenters [j];
modelVec = (x2 - x1, y2 - y1);
x1, y1 = imageMassCenters[i];
x2, y2 = imageMassCenters[j];
imageVec = (x2 - x1, y2 - y1);
rotation = angle(modelVec,imageVec);
rotations.append((i, j, rotation));
scale = length(modelVec)/length(imageVec);
scales.append((i, j, scale));
対応する線の各ペアによって与えられるスケールと回転を計算した後、中央値と回転の平均値を見つけます。これは、中央値とのデルタ以上の差はありません。スケールについても同じです。次に、これらの値を計算に使用するポイントを使用して、変位を計算します。