如何停止迭代通过一个2D数组一旦匹配被发现?



我正在使用EMGU和c#进行图像模板匹配。EMGU查找匹配的方法有点慢,所以我尝试遍历图像(2D数组)来查找匹配。它工作得很好,非常快。但由于某种原因,它会在同一位置找到多个匹配的相同模板,并在其上绘制多次。例如,如果在我的图像中有4个给定模板的匹配,它将为这4个匹配的每个匹配区域绘制10个矩形,因此矩形厚度增加并且总匹配计数永远不会正确。

代码如下:

for (int y = 0; y < Matches.Data.GetLength(0); y++)
{
for (int x = 0; x < Matches.Data.GetLength(1); x++)
{
if (Matches.Data[y, x, 0] >= Threshold) //Set at 0.9
{
Rectangle r = new Rectangle(new Point(x, y), template.Size);
CvInvoke.Rectangle(imgres, r, new MCvScalar(255, 0, 0), 1, LineType.EightConnected, 0);
listBox1.Items.Add(r.Size); // more than 80 rectangles are drawn for 4 matches
}                       
}                    
}

如何在找到每个匹配项一次后停止迭代?

可以使用break;但这在嵌套循环中会很快变得混乱。

让我们从循环快,它们的结构是这样的:

for (declaration; condition; execute after) 
{
// code block
}

由于中间部分是一个简单的条件,您可以添加另一个条件,表明它已完成(或仍在搜索)。在这个例子中只是一个布尔值:

bool stillSearching = true;
for (int i = 0; i < 100 && stillSearching; i++)
{
if (i > 50) //You found your match
{
stillSearching = false;
}
}

这将简单地计数到51,然后如果设置boolean.然后返回for循环,执行i++.然后检查这两个条件:我& lt;100仍然是正确的stillSearching是假的

由于&&整个条件为false然后循环停止

编辑:因为我不确定你需要满足什么条件,所以我只添加一个if

bool searching = true;
for (int y = 0; y < Matches.Data.GetLength(0) && searching; y++)
{
for (int x = 0; x < Matches.Data.GetLength(1) && searching; x++)
{
if (Matches.Data[y, x, 0] >= Threshold) 
{
Rectangle r = new Rectangle(new Point(x, y), template.Size);
CvInvoke.Rectangle(imgres, r, new MCvScalar(255, 0, 0), 1, LineType.EightConnected, 0);
listBox1.Items.Add(r.Size); 
}
if ( /*your condtion here*/ )
{
searching = false;
}   
}                    
}

使用return语句

为了保持整洁,将循环和操作保持在单独的短方法中。

for (int y = 0; y < Matches.Data.GetLength(0); y++)
{
for (int x = 0; x < Matches.Data.GetLength(1); x++)
{
if (Matches.Data[y, x, 0] >= Threshold)
{
DoSomethingWithMatch(x, y);
return;
}
}
}

另外,出于性能原因,不应该在循环中访问c#属性。首先将Matches.Data保存在一个变量中,然后遍历该变量。

你可以使用break跳出循环,但它只能让你跳出最近的循环。解决这个问题的方法是设置flag来指示是否应该跳出外部循环。考虑以下内容:

for (int y = 0; y < Matches.Data.GetLength(0); y++)
{
bool matchFound = false;
for (int x = 0; x < Matches.Data.GetLength(1); x++)
{
if (Matches.Data[y, x, 0] >= Threshold) //Set at 0.9
{
Rectangle r = new Rectangle(new Point(x, y), template.Size);
CvInvoke.Rectangle(imgres, r, new MCvScalar(255, 0, 0), 1, LineType.EightConnected, 0);
listBox1.Items.Add(r.Size); // more than 80 rectangles are drawn for 4 matches
matchFound = true;
break;
}                       
}
if(matchFound) 
{
break;
}               
}

相关内容

  • 没有找到相关文章

最新更新