【发布时间】:2021-06-07 14:57:28
【问题描述】:
我知道这个话题在互联网上被广泛讨论,但是我找不到我的问题的答案......
所以我的最终目标是提取图像的一部分并将其与“模板”进行比较。 我已经提取并裁剪了图像的一部分,所以这不是问题。
我遇到的问题是尝试将其与模板进行比较。模板最初是 SVG,所以我将其转换为 JPG 并删除了 alpha 通道。
实际图像取自网络摄像头,因此它是彩色的,但我可以轻松设置阈值以仅保留黑色/白色。
所以我尝试了 3 种方法。
1. SIFT algorithm.
private void MatchBySift(Mat src1, Mat src2)
{
var gray1 = new Mat();
var gray2 = new Mat();
Cv2.CvtColor(src1, gray1, ColorConversionCodes.BGR2GRAY);
Cv2.CvtColor(src2, gray2, ColorConversionCodes.BGR2GRAY);
var sift = SIFT.Create();
// Detect the keypoints and generate their descriptors using SIFT
KeyPoint[] keypoints1, keypoints2;
var descriptors1 = new Mat(); //<float>
var descriptors2 = new Mat(); //<float>
sift.DetectAndCompute(gray1, null, out keypoints1, descriptors1);
sift.DetectAndCompute(gray2, null, out keypoints2, descriptors2);
// Match descriptor vectors
var bfMatcher = new BFMatcher(NormTypes.L2, false);
var flannMatcher = new FlannBasedMatcher();
DMatch[] bfMatches;
DMatch[] flannMatches;
try
{
bfMatches = bfMatcher.Match(descriptors1, descriptors2);
flannMatches = flannMatcher.Match(descriptors1, descriptors2);
}
catch
{
bfMatches = new DMatch[0];
flannMatches = new DMatch[0];
}
// Draw matches
var bfView = new Mat();
Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, bfMatches, bfView);
var flannView = new Mat();
Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, flannMatches, flannView);
Console.WriteLine("BF Matches: " + bfMatches.Length);
Console.WriteLine("Flann Matches: " + flannMatches.Length);
using (new Window("SIFT matching (by BFMather)", bfView))
using (new Window("SIFT matching (by FlannBasedMatcher)", flannView))
{
Cv2.WaitKey();
}
}
2. SURF Algorithm
private void MatchBySurf(Mat src1, Mat src2)
{
var gray1 = new Mat();
var gray2 = new Mat();
Cv2.CvtColor(src1, gray1, ColorConversionCodes.BGR2GRAY);
Cv2.CvtColor(src2, gray2, ColorConversionCodes.BGR2GRAY);
var surf = SURF.Create(200, 4, 2, true);
// Detect the keypoints and generate their descriptors using SURF
KeyPoint[] keypoints1, keypoints2;
var descriptors1 = new Mat(); //<float>
var descriptors2 = new Mat(); //<float>
surf.DetectAndCompute(gray1, null, out keypoints1, descriptors1);
surf.DetectAndCompute(gray2, null, out keypoints2, descriptors2);
// Match descriptor vectors
var bfMatcher = new BFMatcher(NormTypes.L2, false);
var flannMatcher = new FlannBasedMatcher();
DMatch[] bfMatches;
DMatch[] flannMatches;
try
{
bfMatches = bfMatcher.Match(descriptors1, descriptors2);
flannMatches = flannMatcher.Match(descriptors1, descriptors2);
}
catch
{
bfMatches = new DMatch[0];
flannMatches = new DMatch[0];
}
// Draw matches
var bfView = new Mat();
Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, bfMatches, bfView);
var flannView = new Mat();
Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, flannMatches, flannView);
Console.WriteLine("BF Matches: " + bfMatches.Length);
Console.WriteLine("Flann Matches: " + flannMatches.Length);
/*
using (new Window("SURF matching (by BFMather)", bfView))
using (new Window("SURF matching (by FlannBasedMatcher)", flannView))
{
Cv2.WaitKey();
}
*/
}
3. Hash comparison
private void MatchByHash(Mat src1, Mat src2)
{
Bitmap bit1 = BitmapConverter.ToBitmap(src1);
Bitmap bit2 = BitmapConverter.ToBitmap(src2);
List<bool> hash1 = GetHash(bit1);
List<bool> hash2 = GetHash(bit2);
int equalElements = hash1.Zip(hash2, (i, j) => i == j).Count(eq => eq);
Console.WriteLine("Match by Hash: " + equalElements);
}
public List<bool> GetHash(Bitmap bmpSource)
{
List<bool> lResult = new List<bool>();
//create new image with 16x16 pixel
Bitmap bmpMin = new Bitmap(bmpSource, new System.Drawing.Size(16, 16));
for (int j = 0; j < bmpMin.Height; j++)
{
for (int i = 0; i < bmpMin.Width; i++)
{
//reduce colors to true / false
lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f);
}
}
return lResult;
}
为什么我对结果不满意
- SIFT 和 SURF
比较上述图像时,我会根据匹配数得到一定的相似性。问题是当我使用不同的template image 时,我总是得到相同的数字......我认为这是因为没有颜色,但我需要在这里澄清
- 哈希
在其他“模板”上使用时,我得到了更高的结果!这基本上消除了这种方法,除非它可以以某种方式改进......
我也听说过 ORB 算法,但我还没有尝试实现它。这在我的场合会更好吗?
如果我可以尝试任何其他方法,请指出正确的方向!
谢谢
【问题讨论】:
标签: c# opencv image-processing image-comparison