我正在尝试构建一个解决谜题的应用程序(尝试开发图算法),而且我不想一直手动输入样本输入。
编辑:我不打算构建游戏。我正在尝试建立一个扮演“SpellSeeker”游戏的代理人
说我在屏幕上有一个图像(见附件),上面有数字,我知道这些框的位置,我有这些数字的确切图像。我想要做的只是告诉相应的盒子上有哪个图像(数字)。
Numbers http://i46.tinypic.com/3089vyt.jpg
所以我想我需要实现
bool isImageInsideImage(Bitmap numberImage,Bitmap Portion_Of_ScreenCap)
或类似的东西。
我尝试的是(使用AForge库)
public static bool Contains(this Bitmap template, Bitmap bmp)
{
const Int32 divisor = 4;
const Int32 epsilon = 10;
ExhaustiveTemplateMatching etm = new ExhaustiveTemplateMatching(0.9f);
TemplateMatch[] tm = etm.ProcessImage(
new ResizeNearestNeighbor(template.Width / divisor, template.Height / divisor).Apply(template),
new ResizeNearestNeighbor(bmp.Width / divisor, bmp.Height / divisor).Apply(bmp)
);
if (tm.Length == 1)
{
Rectangle tempRect = tm[0].Rectangle;
if (Math.Abs(bmp.Width / divisor - tempRect.Width) < epsilon
&&
Math.Abs(bmp.Height / divisor - tempRect.Height) < epsilon)
{
return true;
}
}
return false;
}
但在此图像中搜索黑点时返回false。
我该如何实现?
答案 0 :(得分:5)
我正在回答我的问题,因为我找到了解决方案:
this为我解决了问题:
System.Drawing.Bitmap sourceImage = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\1.jpg");
System.Drawing.Bitmap template = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\2.jpg");
// create template matching algorithm's instance
// (set similarity threshold to 92.5%)
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.921f);
// find all matchings with specified above similarity
TemplateMatch[] matchings = tm.ProcessImage(sourceImage, template);
// highlight found matchings
BitmapData data = sourceImage.LockBits(
new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
ImageLockMode.ReadWrite, sourceImage.PixelFormat);
foreach (TemplateMatch m in matchings)
{
Drawing.Rectangle(data, m.Rectangle, Color.White);
MessageBox.Show(m.Rectangle.Location.ToString());
// do something else with matching
}
sourceImage.UnlockBits(data);
唯一的问题是它为所述游戏找到了所有(58)盒子。但是将值0.921f更改为0.98使其变得完美,即它只找到指定数字的图像(模板)
编辑:我实际上必须为不同的图片输入不同的相似度阈值。我通过尝试找到了优化的值,最后我有一个像
这样的函数float getSimilarityThreshold(int number)
答案 1 :(得分:1)
更好的方法是构建一个自定义类,它包含您需要的所有信息,而不是依赖于图像本身。
例如:
public class MyTile
{
public Bitmap TileBitmap;
public Location CurrentPosition;
public int Value;
}
通过这种方式,您可以“移动”tile类并从Value
字段中读取值,而不是分析图像。你只需将该类所持有的任何图像绘制到它当前所持的位置。
您的图块可以保存在如下数组中:
private list<MyTile> MyTiles = new list<MyTile>();
根据需要扩展类(并记住在不再需要时处理这些图像)。
如果确实想要查看图片中是否有图像,您可以查看我为其他帖子写的这个扩展名(虽然在VB代码中):
Vb.Net Check If Image Existing In Another Image