因此,在業餘時間,我喜歡嘗試通過計算機視覺技術自動化各種遊戲。通常,使用濾鏡和像素檢測的模板匹配對我來說工作得很好。不過,我最近決定嘗試使用特徵匹配來瀏覽關卡。我想要的是保存整個探索地圖的過濾圖像。 EMGU中的衝浪特徵檢測/匹配問題2.4
然後到小地圖從每隔幾秒鐘後,畫面複製並以同樣的方式進行過濾,並使用衝浪匹配到我的全地圖,應該有希望給我一個玩家當前位置(本場比賽的中心將是玩家在地圖上)。按預期這個工作的一個很好的例子是以下(滿地圖找到的匹配在左邊,右邊是迷你地圖圖像。
我所遇到的麻煩是在EMGU庫衝浪匹配似乎找到了不正確的匹配在
有時候很多情況下,它不是絕對的壞象下面這樣:
我有種看到最新發生的是,它找到更好的匹配在不同位置的關鍵點因爲Surf應該是規模不變的。我對EMGU圖書館或Surf沒有足夠的瞭解,因此它只接受類似於最初好的匹配的匹配,並且拋棄這些不好的匹配,或者調整它,以便那些不錯的匹配是好的匹配。
我正在使用新的2.4 EMGU代碼庫,我的SURF匹配代碼如下。我真的很想讓它達到這一點,以便它只返回總是相同大小的匹配(正常小地圖大小與完整地圖上縮放比例的比例),以便我不會得到一些瘋狂的形狀匹配。
public Point MinimapMatch(Bitmap Minimap, Bitmap FullMap)
{
Image<Gray, Byte> modelImage = new Image<Gray, byte>(Minimap);
Image<Gray, Byte> observedImage = new Image<Gray, byte>(FullMap);
HomographyMatrix homography = null;
SURFDetector surfCPU = new SURFDetector(100, false);
VectorOfKeyPoint modelKeyPoints;
VectorOfKeyPoint observedKeyPoints;
Matrix<int> indices;
Matrix<byte> mask;
int k = 6;
double uniquenessThreshold = 0.9;
try
{
//extract features from the object image
modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null);
Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints);
// extract features from the observed image
observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null);
Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints);
BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2);
matcher.Add(modelDescriptors);
indices = new Matrix<int>(observedDescriptors.Rows, k);
using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
{
matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
mask = new Matrix<byte>(dist.Rows, 1);
mask.SetValue(255);
Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
}
int nonZeroCount = CvInvoke.cvCountNonZero(mask);
if (nonZeroCount >= 4)
{
nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
if (nonZeroCount >= 4)
homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
}
if (homography != null)
{ //draw a rectangle along the projected model
Rectangle rect = modelImage.ROI;
PointF[] pts = new PointF[] {
new PointF(rect.Left, rect.Bottom),
new PointF(rect.Right, rect.Bottom),
new PointF(rect.Right, rect.Top),
new PointF(rect.Left, rect.Top)};
homography.ProjectPoints(pts);
Array.ConvertAll<PointF, Point>(pts, Point.Round);
Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);
result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);
return new Point(Convert.ToInt32((pts[0].X + pts[1].X)/2), Convert.ToInt32((pts[0].Y + pts[3].Y)/2));
}
}
catch (Exception e)
{
return new Point(0, 0);
}
return new Point(0,0);
}
你會推薦我用什麼方法來實現我想要完成的目標? – OPcorki
謝謝,看起來我有一些閱讀要做! – OPcorki
不客氣。我可以爲您提供另一種類似的方法,該方法基於名爲史密斯沃特曼的本地比對算法(我在大學時期將其應用於序列蛋白比對中)。以下是該論文的鏈接:http://rogerioferis.com/publications/FerisNordia08.pdf –